hdu 1811 Rank of Tetris
//hdu 1811 Rank of Tetris //并查集+拓扑 //思路:用并查集把相等的点归到一起,再用拓扑 //纠结这题纠结了一整天,看了n多的博客感觉这个不错 //http://972169909-qq-com.iteye.com/blog/1052820 #include <stdio.h> #include <string.h> #include <queue> using namespace std; #define comein freopen("in.txt", "r", stdin); #define N 10005 #define M 20005 #define INF 1<<30 #define eps 1e-5 struct edge { int win, lost, next; }adja[M]; int tot; //记录插入邻接表的个数 int degree[N]; int win[M], lost[M], head[N], set[N]; int find(int root) { if(root == set[root]) return root; return set[root] = find(set[root]); } void add_edge(int r_a, int r_b) { degree[r_b]++; adja[++tot].win = r_a; adja[tot].lost = r_b; adja[tot].next = head[r_a]; head[r_a] = tot; } void topo(int n_node, int all) { queue<int>que; bool uncer = false; for(int i = 0; i < n_node; ++i)//要集合根节点且度为0的才可入队,若只判断 if(degree[i] == 0 && i == find(i)) //degree[find(i)]==0,可能会重复入队 que.push(i); while(!que.empty()) { if(que.size() > 1) uncer = true; int now = que.front(); que.pop(); all--; for(int i = head[now]; i != -1; i = adja[i].next) { if(--degree[ adja[i].lost ] == 0) que.push( adja[i].lost ); } } if(all > 0) //剩下的集合数大于1,则存在环 puts("CONFLICT"); else if(uncer == true) puts("UNCERTAIN"); else puts("OK"); } int main() { // comein int n_node, n_pair; while(scanf("%d%d", &n_node, &n_pair) == 2) { for(int i = 0; i <= n_node; ++i) //初始化并查集 set[i] = i; int cnt = 0, all = n_node; //若相等的点看做一个点,cnt记录总的点数 for(int i = 0; i < n_pair; ++i) { int wn, lt; char ra; scanf("%d %c %d", &wn, &ra, <); if(ra == '=') { //这里要先求出来r_a和r_b,然后下面要用set[r_a] = r_b //或set[r_b] = r_a,也不知道为什么,一天下来都在找bug //无缘无故就被de掉了,提交了30几次,有的这里不用这样也可以ac //有的不能,快崩溃了 int r_a = find(wn), r_b = find(lt); if(r_a != r_b) { set[r_a] = r_b; all--; } } else if(ra == '>') { win[++cnt] = wn; lost[cnt] = lt; } else { win[++cnt] = lt; lost[cnt] = wn; } } memset(adja, 0, (n_pair+5)*sizeof(edge)); for(int i = 0; i < n_node; ++i) { head[i] = -1; degree[i] = 0; } tot = 0; bool flag = false; for(int i = 1; i <= cnt; ++i) { int r_a = find(win[i]), r_b = find(lost[i]); if(r_a == r_b) //上面的已经把'='的情况合并起来了 { //这里都是处理不等的,如果出现相等的,说明冲突了 flag = true; break; } add_edge(r_a, r_b); } if(flag == true) { puts("CONFLICT"); continue; } topo(n_node, all); } return 0; }