HDU 1881
来源:互联网 发布:淘宝怎么举报卖家假货 编辑:程序博客网 时间:2024/06/06 14:18
思路:一开始以为rating相同的点就直接比较rp然后建图,后来想想不对,因为这样发现不了冲突。后来一想对于rating相同的点可以不用排序,因为对于这些点,他们的rp必然不相同,也就是说在这些点的内部必然存在唯一的且合理的排序,因此只需将要将这些点合并成一个点即可,需要用到并查集的知识。
把所有点按上述方法处理后就会得到一些点(暂且称为“有效点”),对于这些有效点再进行拓扑排序即可。
冲突情形:到最后存在环,或者出现a > b,b > c 且 c >a;
不确定情形:同一层中不止一个点入度为0;
确定情形:除以上两种情形;
#include<stdio.h>#include<string.h>typedef struct{ int to; int next;}EdgeNode;int cnt;char str[6];EdgeNode Edge[20005];int father[10005],depth[10005];int L[10005],M[10005],R[10005];int head[10005],indegree[10005];int vis[10005],node[10005],temp[10005];void init(int n){ int i; cnt = 0; memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); memset(indegree,0,sizeof(indegree)); for(i = 0;i < n;i ++) { father[i] = i; depth[i] = 0; }}int find(int x){ if(x == father[x]) return x; return father[x] = find(father[x]);}void uint(int x,int y){ x = find(x); y = find(y); if(x == y) return ; if(depth[x] < depth[y]) father[x] = y; else { if(depth[x] > depth[y]) father[y] = x; else { father[x] = y; depth[y]++; } } return ;}void add_edge(int n,int m){ Edge[cnt].to = m; Edge[cnt].next = head[n]; head[n] = cnt++;}int main(void){ int a,b,n,m,i,j,k; int sum,flag_U,flag_C; while(~scanf("%d %d",&n,&m)) { init(n); flag_U = flag_C = 0; for(i = 1;i <= m;i ++) { scanf("%d %c %d",&L[i],&M[i],&R[i]); if(M[i] == '=') { uint(L[i],R[i]); } } for(i = 1;i <= m;i ++) { if(M[i] == '=') continue ; a = find(L[i]); b = find(R[i]); if(a == b) { flag_C = 1; break ; } else { if(M[i] == '>') { add_edge(b+1,a+1); indegree[a+1]++; } else { add_edge(a+1,b+1); indegree[b+1]++; } } } for(i = 1;i <= n;i ++) { sum = 0; for(j = 1;j <= n;j ++) { if(indegree[j] == 0 && vis[j] == 0 && father[j-1] == j-1) temp[sum++] = j; } if(sum > 1) flag_U = 1; for(j = 0;j < sum;j ++) { vis[temp[j]] = 1; for(k = head[temp[j]];k != -1;k = Edge[k].next) { if(!vis[Edge[k].to]) indegree[Edge[k].to]--; } } } for(i = 1;i <= n;i ++) { if(indegree[i] && father[i-1] == i-1) { flag_C = 1; break ; } } if(!(flag_C+flag_U)) printf("OK\n"); if(flag_C) printf("CONFLICT\n"); if(flag_U && !flag_C) printf("UNCERTAIN\n"); } return 0;}
0 0