[POJ2912]Rochambeau(并查集)

传送门

 

题意:

n个人分成三组,玩石头剪子布游戏,同一组的人只能出同样固定的的手势,其中有一个是裁判不属于任何组,可以出任意手势,给出m个信息x op y 表示x,y是从三个组里面随机抽取的或者是裁判,他们之间的输赢关系。让你判断最少在第几组信息时,可以唯一判断出裁判,并将裁判号,以及在第几组后判断出来的输出。

思路:
注意这里是能够唯一确定,也就是存在确定的唯一一个裁判。那么我们可以从n个人里面枚举裁判,然后判断除去裁判之后是否还存在矛盾的关系(存在矛盾肯定是裁判在其中导致的),如果存在那么排除该人,记录在第几个信息出现的。枚举完后,如果只存在一个矛盾的人那么这个人就是裁判,如果不存在矛盾,输出Impossible,否则就表示存在多个裁判,输出Can not determine 这里存在矛盾的判断就是用分类并查集处理的了。

 

——代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #define N 1000001
 4 #define max(x, y) ((x) > (y) ? (x) : (y))
 5 
 6 int n, m, k, ans, cnt;
 7 int a[N], b[N], f[N], d[N], err[N];
 8 char s[N];
 9 
10 inline int find(int x)
11 {
12     if(x ^ f[x])
13     {
14         int fx = f[x];
15         f[x] = find(f[x]);
16         d[x] = (d[x] + d[fx]) % 3;
17     }
18     return f[x];
19 }
20 
21 int main()
22 {
23     int i, j, fx, fy;
24     while(~scanf("%d %d", &n, &m))
25     {
26         for(i = 0; i < m; i++) scanf("%d %c %d", &a[i], &s[i], &b[i]);
27         memset(err, 0, sizeof(err));
28         for(i = 0; i < n; i++)
29         {
30             for(j = 0; j < n; j++) f[j] = j, d[j] = 0;
31             for(j = 0; j < m; j++)
32             {
33                 if(a[j] == i || b[j] == i) continue;
34                 fx = find(a[j]);
35                 fy = find(b[j]);
36                 if(fx == fy)
37                 {
38                     if(s[j] == '=' && d[a[j]] ^ d[b[j]])
39                     {
40                         err[i] = j + 1;
41                         break;
42                     }
43                     if(s[j] == '<' && (d[a[j]] - d[b[j]] + 3) % 3 != 1 && (d[b[j]] - d[a[j]] + 3) % 3 != 2)
44                     {
45                         err[i] = j + 1;
46                         break;
47                     }
48                     if(s[j] == '>' && (d[a[j]] - d[b[j]] + 3) % 3 != 2 && (d[b[j]] - d[a[j]] + 3) % 3 != 1)
49                     {
50                         err[i] = j + 1;
51                         break;
52                     }
53                 }
54                 else
55                 {
56                     if(s[j] == '=')
57                     {
58                         d[fx] = (d[b[j]] - d[a[j]] + 3) % 3;
59                         f[fx] = fy;
60                     }
61                     if(s[j] == '<')
62                     {
63                         d[fx] = (d[b[j]] - d[a[j]] + 4) % 3;
64                         f[fx] = fy;
65                     }
66                     if(s[j] == '>')
67                     {
68                         d[fx] = (d[b[j]] - d[a[j]] + 5) % 3;
69                         f[fx] = fy;
70                     }
71                 }
72             }
73         }
74         k = ans = cnt = 0;
75         for(i = 0; i < n; i++)
76         {
77             if(!err[i])
78             {
79                 cnt++;
80                 k = i;
81             }
82             ans = max(ans, err[i]);
83         }
84         if (cnt == 0) puts("Impossible");
85         else if (cnt == 1) printf("Player %d can be determined to be the judge after %d lines\n", k, ans);
86         else puts("Can not determine");
87     }
88 }
View Code

 

posted @ 2017-06-15 14:22  zht467  阅读(152)  评论(0编辑  收藏  举报