1811 (並查集 + 拓撲排序)
阿新 • • 發佈:2018-12-13
讀題可以知道當成環的時候會有衝突,當不止有一個拓撲排序的時候資訊不完全。
當有相等的時候可以用並查集把他們當成一個節點來處理;
程式碼如下:
#include<stdio.h> #include<string.h> #define mmset(a,b) memset(a,b,sizeof(a)) const int N = 100005; const int M = 200005; struct edge { int x, y, flag ; }; struct node { int to,w,next; }; node edges[M]; edge data[M]; int head[N],indegree[M],que[M],father[N] ,index = 0, que_len = 0, n , m, len = 0,sum = n,flag = 0; void init() { for(int i = 0; i <= n; i++) { father[i] = i; } mmset(head,-1); mmset(indegree,0); len = 0, sum = n, index = 0, que_len = 0,flag = 0; } void addEdge(int a, int b, int c) { edges[len].to = b, edges[len].w = c; edges[len].next = head[a], head[a] = len++; } int find(int x) { if(x != father[x]) { father[x] = find(father[x]); } return father[x]; } void merge(int fx, int fy) { father[fx] = fy; } /* 3 3 0 > 1 1 < 2 0 > 2 4 4 1 = 2 1 > 3 2 > 0 0 > 1 3 3 1 > 0 1 > 2 2 < 1 Sample Output OK CONFLICT UNCERTAIN */ int main() { while(~scanf("%d %d",&n,&m)) { init(); for(int i = 0; i < m; i++) { int a,b; char sym[2]; scanf("%d %s %d",&a,sym,&b) ; if(sym[0] == '=') { int fx = find(a); int fy = find(b); if(fx != fy) //把相等關係的節點當成一個節點來處理 { sum--; merge(fx,fy); } data[i].x = a, data[i].y = b, data[i].flag = 0; } else if(sym[0] == '<') { data[i].x = a, data[i].y = b, data[i].flag = 1; } else if(sym[0] == '>') { data[i].x = a, data[i].y = b, data[i].flag = 2; } } for(int i = 0; i < m; i++) { if(data[i].flag == 0) continue; int fx = find(data[i].x), fy = find(data[i].y); if(data[i].flag == 1) { addEdge(fx,fy,1); indegree[fy]++; } else if(data[i].flag == 2) { addEdge(fy,fx,1); indegree[fx]++; } } for(int i = 0; i < n; i++) { if(father[i] == i && indegree[i] == 0) //把相等關係的節點當成一個節點來處理 { que[index++] = i; que_len++; } } for(int i = 0; i < index; i++) { if(que_len > 1) //當存在多個拓撲排序的時候說明資訊不完全; { flag = 1; } int now = que[i]; que_len--; sum--; for(int j = head[now]; j != -1; j = edges[j].next) { indegree[edges[j].to]--; if(indegree[edges[j].to] == 0) { que[index++] = edges[j].to; que_len++; } } } if(sum > 0) //當sum > 0的時候說明會成環,這時候說明資訊有衝突 { printf("CONFLICT\n"); } else if(flag == 1) { printf("UNCERTAIN\n"); } else { printf("OK\n"); } } return 0; }