【HDU 1811 Rank of Tetris】 并查集+拓扑排序

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1811

 

题目大意:给你一些ranking的比值关系,然后利用这些比值关系进行排名,让你确定是否能制作出排行榜,是的话就输出"OK",否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出"CONFLICT")。如果信息中同时包含冲突且信息不完全,就输出"CONFLICT"。

 

解题思路:

1、利用并查集操作,将相关联的 '=' 两边的数字先放存在一个集合里。

2、然后确定 ‘>’ , '<' 两边的数字是否和已存等号集合里的关系有重复,如果有直接输出"CONFLICT",否则建立领结表。这里要注意了,我就是在这里WA了一下午,因为等号关系已经确定,你现在要把存有具有相关联等号关系的数字的集合看做一个点,这里我们用每个集合的根节点代替。

3、开始拓扑排序,当拓扑排序完了遍历的节点小于n个,则可以说明拓扑过程中入度为0的节点没有n个,也就是拓扑序列中存在环。

4、当拓扑序列中同时出现两个或两个以上入度为0的节点时,说明信息不完全。

5、最后一种情况就只剩下满足的了。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<vector>
 5 #include<queue>
 6 #include<cstdio>
 7 using namespace std;
 8 
 9 const int maxn=10005;
10 int deg[maxn];
11 int father[maxn];
12 int st[2*maxn];
13 int sd[2*maxn];
14 char ch[2*maxn];
15 vector<int>vt[maxn];
16 
17 int find(int x)
18 {
19     while(x!=father[x])
20         x=father[x];
21     return x;
22 }
23 
24 int main()
25 {
26     int n, m,u, v, fa, fb;
27     while(cin >> n >> m)
28     {
29         int flag=0, num=n;
30         for(int i=0; i<=n; i++)
31             vt[i].clear(), father[i]=i, deg[i]=0;
32         for(int i=0; i<m; i++)
33         {
34             scanf("%d %c %d",&st[i],&ch[i],&sd[i]);
35             if(ch[i]=='=')
36             {
37                 fa=find(st[i]);
38                 fb=find(sd[i]);
39                 if(fa!=fb)
40                   father[fb]=fa, num--;
41             }
42         }
43         for(int i=0; i<m; i++)
44         {
45             if(ch[i]=='>')
46             {
47                 u=st[i], v=sd[i];
48                 fa=find(u);
49                 fb=find(v);
50                 if(fa==fb) flag=1;
51                 deg[fb]++;
52                 vt[fa].push_back(fb);
53             }
54             else if(ch[i]=='<')
55             {
56                 u=st[i], v=sd[i];
57                 fa=find(u);
58                 fb=find(v);
59                 if(fa==fb) flag=1;
60                 deg[fa]++;
61                 vt[fb].push_back(fa);
62             }
63         }
64         if(flag)
65         {
66             puts("CONFLICT");
67             continue;
68         }
69         int cnt=0;
70         queue<int>q;
71         for(int i=0; i<n; i++)
72             if(deg[i]==0&&i==find(i))
73                 q.push(i);
74         while(!q.empty())
75         {
76             if(q.size()>1) flag=2;
77             int p=q.front();
78             q.pop();
79             num--;
80             for(int i=0; i<vt[p].size(); i++)
81             {
82                 int v=vt[p][i];
83                 deg[v]--;
84                 if(deg[v]==0)
85                     q.push(v);
86             }
87         }
88         if(num>0)
89             puts("CONFLICT");
90         else if(flag)
91             puts("UNCERTAIN");
92         else
93             puts("OK");
94     }
95     return 0;
96 }

 

 

posted @ 2013-01-11 18:46  Mr. Ant  阅读(311)  评论(0编辑  收藏  举报