1 #include <stdio.h>
2 #include <string.h>
3 #include <vector>
4 #include <queue>
5 using namespace std;
6 struct node//边
7 {
8 int a, b;//顶点
9 char ch;//运算符
10 }c[10005];
11 vector<int>map[10005];//map数组存贮邻接表 (大佬都是这么开数组的)
12 int n, m, sum, in[10005], fa[10005];//in数组表示入度,fa[i]表示顶点i所在集合的根节点
13
14 int find(int x)//查找根节点
15 {
16 if (fa[x] != x) fa[x] = find(fa[x]);
17 return fa[x];
18 }
19
20 bool comb(int x, int y)//合并集合
21 {
22 x = find(x);
23 y = find(y);
24 if (x == y)
25 return false;
26 else
27 {
28 fa[y] = x;
29 return true;
30 }
31 }
32
33 void init()//初始化
34 {
35 for (int i = 0; i<n; i++)
36 fa[i] = i;
37 }
38
39 void top_sort()//queue实现拓扑排序
40 {
41 queue<int>s;
42 int flag = 0;
43 for (int i = 0; i<n; i++)
44 {
45 //找到入度为零的切祖宗为自己的加入到队列中
46 if (in[i] == 0 && fa[i] == i)
47 s.push(i);
48 }
49 while (!s.empty())
50 {
51 if (s.size() > 1)//即使发现信息不完整也要继续运行下去,因为如果信息同时不完整和冲突都是CONFLICT
52 flag = 1;
53 int pos = s.front();
54 s.pop(), sum--; //记录下运行的次数
55 for (int i = 0; i<map[pos].size(); i++)
56 {
57 in[map[pos][i]]--;
58 if (in[map[pos][i]] == 0)
59 s.push(map[pos][i]);
60 }
61 }
62 if (sum>0) printf("CONFLICT\n"); //冲突,即有多个入度为零且祖宗为自己的出现
63 else if (flag) printf("UNCERTAIN\n");
64 else printf("OK\n");
65 }
66
67 int main()
68 {
69 while (scanf("%d %d", &n, &m) != EOF)
70 {
71 sum = n;
72 init();
73 memset(map, 0, sizeof(map));
74 memset(in, 0, sizeof(in));
75 for (int i = 0; i<m; i++)
76 {
77 scanf("%d %c %d", &c[i].a, &c[i].ch, &c[i].b);
78 //如果相等,就合并为同一个集合
79 if (c[i].ch == '=')
80 {
81 if (comb(c[i].a, c[i].b))
82 sum--;
83 }
84 }
85 for (int i = 0; i<m; i++)
86 {
87 if (c[i].ch == '=')
88 continue;
89 int x = find(c[i].a);
90 int y = find(c[i].b);
91 if (c[i].ch == '>')
92 {
93 map[x].push_back(y);
94 in[y]++;
95 }
96 else
97 {
98 map[y].push_back(x);
99 in[x]++;
100 }
101 }
102 top_sort();
103 }
104 //system("pause");
105 return 0;
106 }