其實好久都沒寫題解了 本來也不想寫這篇題解的 但是上網一看所有題解長得一模一樣 也沒有什麼具體分析(畢竟天下題解一大抄嘛 233333) 還是打算寫寫這個題的分析吧
具體分析:
首先想想 如果答案成爲ok 那麼這些關係最終應該組成一條鏈纔是 如果有環那麼結果應該衝突 如果是一顆樹 那麼兩顆子樹的相對關係沒法確定 所以最後的圖一定是一條鏈才能滿足所有關係
但是這題有一個等於關係有點麻煩 這時候我們可以用並查集縮點 例如A = B, B = C, C = D, 那麼可以把A, B, C, D視爲一個點, (都長得一樣自然可以視爲一體)最後求一遍拓撲序 如果是一條鏈 那麼這個關係我們是能確定的 如果有環 那麼關係衝突 如果是樹 那就是信息不足
#include <bits/stdc++.h>
#define F first
#define S second
#define PLL pair<ll, ll>
#define PII pair<int, int>
#define PDD pair<double, double>
#define met(a, b) memset(a, b, sizeof(a))
#define FAST ios::sync_with_stdio(false)
typedef long long ll;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int MOD = 1e9 + 7;
const int N = 1e4 + 10, M = N * 2;
using namespace std;
struct EdgeNode {
int to, next;
} edges[M];
int idx, h[N];
int a[N], b[N], F[N];
char op[N];
int ret, que[N], din[N];
inline void add(int u, int v) {
edges[idx] = {v, h[u]}, h[u] = idx++;
return ;
}
inline int Find(int x) {
if (F[x] != x) F[x] = Find(F[x]);
return F[x];
}
inline void Union(int x, int y) {
F[Find(y)] = Find(x);
return ;
}
void Topsort(int n) {
bool flag = true;
int hh = 0, tt = -1;
for (int i = 0; i < n; i++) {
if (!din[i] && Find(i) == i) que[++tt] = i;
}
while (hh <= tt) {
if (tt - hh > 0) flag = false; //如果隊列裏數量大於一 那麼就形成一棵樹
int q = que[hh++];
ret--;
for (int i = h[q]; ~i; i = edges[i].next) {
int to = edges[i].to;
if (--din[to] == 0) que[++tt] = to;
}
}
if (ret > 0) printf("CONFLICT\n"); //如果ret > 0 那麼就形成一個環 至於爲什麼 讀者可以自己思考一下
else if (!flag) printf("UNCERTAIN\n");
else printf("OK\n");
return ;
}
void init(int n) {
idx = 0, ret = n;
met(h, -1), met(din, 0);
for (int i = 0; i < N; i++) F[i] = i;
return ;
}
int main() {
FAST;
int n, m;
while (~scanf("%d %d", &n, &m)) {
init(n);
for (int i = 0; i < m; i++) { //縮點 ret記錄縮點後剩餘點的數量
scanf("%d %c %d", &a[i], &op[i], &b[i]);
if (op[i] == '=' && Find(a[i]) != Find(b[i])) Union(a[i], b[i]), ret--;
}
for (int i = 0; i < m; i++) {
int u = Find(a[i]), v = Find(b[i]);
if (op[i] == '>') add(u, v), din[v]++;
else if (op[i] == '<') add(v, u), din[u]++;
}
Topsort(n);
}
return 0;
}
/*
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The program have no BUG.
*/