hdu1811 并查集+拓扑序

题意:现在有一个排名系统,有一系列信息,分别是 > < = 的比较,而如果最终相等,就会将这些相等的按照序号从小到大排,问给出的信息是否可以确定完整的排序。

由于如果很多点相等,他们肯定能够确定名次,那么我们只要让他们共同拥有与其他点的大小关系就行了。所以就用到了并查集,将相等的点加入并查集,再对并查集排拓扑序,如果能够排出唯一的拓扑序,那么在每个并查集内部也能够有唯一的顺序。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn=1e4+5;
 6 const int maxm=2e4+5;
 7 
 8 int fa[maxn],num,n;
 9 int a[maxm],b[maxm];
10 char c[maxm][10];
11 int head[maxn],point[maxm],nxt[maxm],size;
12 int id[maxn];
13 
14 void init(){for(int i=0;i<n;++i)fa[i]=i;}
15 
16 int find(int x){
17     int r=x,t;
18     while(r!=fa[r])r=fa[r];
19     while(x!=r){
20         t=fa[x];
21         fa[x]=r;
22         x=t;
23     }
24     return r;
25 }
26 
27 int topo(){
28     queue<int>q;
29     bool f=1;
30     for(int i=0;i<n;++i)if(fa[i]==i&&!id[i])q.push(i);
31     int cnt=0;
32     while(!q.empty()){
33         int u=q.front();
34         q.pop();
35         cnt++;
36         if(!q.empty())f=0;
37         for(int i=head[u];~i;i=nxt[i]){
38             int j=point[i];
39             id[j]--;
40             if(!id[j])q.push(j);
41         }
42     }
43     if(cnt!=num)return 0;
44     if(f)return 1;
45     return -1;
46 }
47 
48 void add(int a,int b){
49     point[size]=b;
50     nxt[size]=head[a];
51     head[a]=size++;
52     id[b]++;
53 }
54 
55 int main(){
56     int m;
57     while(scanf("%d%d",&n,&m)!=EOF){
58         memset(id,0,sizeof(id));
59         memset(head,-1,sizeof(head));
60         size=0;
61         init();
62         num=n;
63         for(int i=1;i<=m;++i){
64             scanf("%d%s%d",&a[i],c[i],&b[i]);
65             if(c[i][0]=='='){
66                 int x=find(a[i]),y=find(b[i]);
67                 if(x!=y){
68                     fa[x]=y;
69                     num--;
70                 }
71             }
72         }
73         for(int i=1;i<=m;++i){
74             if(c[i][0]=='>'){
75                 add(find(a[i]),find(b[i]));
76             }
77             else if(c[i][0]=='<'){
78                 add(find(b[i]),find(a[i]));
79             }
80         }
81         int tmp=topo();
82         if(tmp==1)printf("OK
");
83         else if(tmp==0)printf("CONFLICT
");
84         else if(tmp==-1)printf("UNCERTAIN
");
85     }
86 }
View Code
原文地址:https://www.cnblogs.com/cenariusxz/p/4795127.html