【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 }

 

 

你可能感兴趣的:(rank)