poj2912(带权并查集+枚举)

Posted frankchen831x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2912(带权并查集+枚举)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=2912

题意:给n个人,m组关系,玩石头剪刀布的游戏,n个人中除一个人judge以外,其他人属于3个group(即石头、剪刀、布),他们只能出这一个手势,而judge可以随便出,要求能否找到judge和在第几组关系时能最先找到judge。

思路:poj1182食物链的进阶版,与那题不同的是,这里需要枚举0到n-1,枚举i假设其为judge,然后遍历不包含i的所有关系,如果符合条件,则i就是judge,否则其不是judge,记录其判断出不是judge的那条边line(后面要用),遍历结束之后,如果judge数目num<1,则Impossible,若num>1,则Can not determine,若num=1,则其为judge,但需要输出判断其为judge的最小的line,其实也就是其它非judge判断为非judge的边line的最大值,这里有点巧妙。

   其余的就和食物链一样了,x->y=-1(<),0(=),1(>),且 x->z=(x->y+y->z+4)%3-1,公式自己手动算一下就明白了。

AC代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 
 5 struct node{
 6     int x,y;
 7     char c;
 8 }a[2005];
 9 
10 int n,m,root[505],f[505],ans[505],res,num;
11 
12 int getr(int k){
13     if(root[k]==k) return k;
14     else{
15         int tmp=root[k];
16         root[k]=getr(root[k]);
17         f[k]=(f[k]+f[tmp]+4)%3-1;
18         return root[k];
19     }
20 }
21 
22 int main(){
23     while(~scanf("%d%d",&n,&m)){
24         if(!m){
25             if(n==1)
26                 printf("Player 0 can be determined to be the judge after 0 lines
");
27             else
28                 printf("Can not determine");
29             continue;
30         }
31         memset(ans,0,sizeof(ans));
32         num=0;
33         for(int i=1;i<=m;++i)
34             scanf("%d%c%d",&a[i].x,&a[i].c,&a[i].y);
35         for(int i=0;i<n;++i){
36             bool flag=true;
37             for(int j=0;j<n;++j)
38                 root[j]=j,f[j]=0;
39             for(int j=1;j<=m;++j){
40                 if(a[j].x!=i&&a[j].y!=i){
41                     int t1=a[j].x,t2=a[j].y,t3,r1,r2;
42                     if(a[j].c==<) t3=-1;
43                     else if(a[j].c===) t3=0;
44                     else t3=1;
45                     r1=getr(t1),r2=getr(t2);
46                     if(r1==r2){
47                         if(f[t1]!=(t3+f[t2]+4)%3-1){
48                             ans[i]=j;
49                             flag=false;
50                             break;
51                         }
52                     }
53                     else{
54                         root[r2]=r1;
55                         f[r2]=(-((t3+f[t2]+4)%3-1)+f[t1]+4)%3-1;
56                     }
57                 }
58             }
59             if(flag)
60                 ++num,res=i;
61         }
62         if(num<1)
63             printf("Impossible
");
64         else if(num>1)
65             printf("Can not determine
");
66         else{
67             int Max=0;
68             for(int i=0;i<n;++i)
69                 if(ans[i]>Max)
70                     Max=ans[i];
71             printf("Player %d can be determined to be the judge after %d lines
",res,Max);
72         }
73     }
74     return 0;
75 }

 

以上是关于poj2912(带权并查集+枚举)的主要内容,如果未能解决你的问题,请参考以下文章

poj 2912 Rochambeau(枚举+带权并查集)

并查集——poj2236(带权并查集)

POJ 1988 Cube Stacking (带权并查集)

poj1182(带权并查集)

poj1182 带权并查集

POJ 1988 Cube Stacking 带权并查集