码迷,mamicode.com
首页 > 其他好文 > 详细

poj2912 带权并查集

时间:2015-09-08 00:07:26      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:

题意:多个人玩石头剪刀布,每个人提前选定了自己出哪个手势,而其中有一种特殊的人他可以随意出什么手势,问是否能够从给出的一系列石头剪刀布游戏中判断出哪个是特殊的,可以从第几局游戏中判断出来。

首先按照食物链那题的做法,定 0,1,2 做为三种手势就可以了,但是这题非常坑,如果在前面的游戏中就能够判断特殊的人了,那么之后的游戏就算有其他矛盾发生也不管了,所以只能找到错就跳出……不过由于判断是哪个人比较麻烦,不知道哪个人的选择是无效的,就不知道那几次游戏是不正确不能加入并查集的,因此就直接暴力枚举每个人是否为特殊的人,对于涉及这个人的所有游戏都不进行并查集操作,看剩下的游戏中是否会有矛盾,如果有就说明这个人不是特殊的人,否则他就可能是。最后如果只有一个人可能是,就可以判读出来,而判断出来的局数,就是枚举其他所有人出现矛盾的游戏场次的最大值,因为只有否定完其他所有人才能确定这个人是特殊的。

技术分享
 1 #include<stdio.h>
 2 #include<string.h>
 3 const int maxm=505;
 4 
 5 int fa[maxm],num[maxm],wa[maxm];
 6 struct ques{
 7     int a,b,c;
 8 }q[2005];
 9 
10 void init(int n){
11     for(int i=0;i<=n;++i){
12         fa[i]=i;
13         num[i]=0;
14     }
15 }
16 
17 int find(int x){
18     int r=x,t1,t2,c=0;
19     while(r!=fa[r]){
20         c+=num[r];
21         r=fa[r];
22     }
23     while(x!=r){
24         t1=fa[x];
25         t2=c-num[x];
26         num[x]=c%3;
27         fa[x]=r;
28         c=t2;
29         x=t1;
30     }
31     return r;
32 }
33 
34 int main(){
35     int n,m;
36     while(scanf("%d%d",&n,&m)!=EOF){
37         for(int i=1;i<=m;++i){
38             char c;
39             scanf("%d",&q[i].a);
40             c=getchar();
41             while(c!==&&c!=<&&c!=>)c=getchar();
42             if(c===)q[i].c=0;
43             else if(c==<)q[i].c=1;
44             else if(c==>)q[i].c=2;
45             scanf("%d",&q[i].b);
46         }
47         memset(wa,-1,sizeof(wa));
48         for(int i=0;i<n;++i){
49             init(n);
50             for(int j=1;j<=m;++j){
51                 if(q[j].a==i||q[j].b==i)continue;
52                 int x=find(q[j].a),y=find(q[j].b);
53                 if(x!=y){
54                     fa[x]=y;
55                     num[x]=((num[q[j].b]+q[j].c-num[q[j].a])%3+3)%3;
56                 }
57                 else{
58                     if((num[q[j].b]+q[j].c)%3!=num[q[j].a]){wa[i]=j;break;}
59                 }
60             }
61         }
62         int cnt=0,ans1,ans2=0;
63         for(int i=0;i<n;++i){
64             if(wa[i]==-1){
65                 cnt++;
66                 ans1=i;
67             }
68             if(wa[i]>ans2)ans2=wa[i];
69         }
70         if(!cnt)printf("Impossible\n");
71         else if(cnt>1)printf("Can not determine\n");
72         else printf("Player %d can be determined to be the judge after %d lines\n",ans1,ans2);
73     }
74     return 0;
75 }
View Code

 

poj2912 带权并查集

标签:

原文地址:http://www.cnblogs.com/cenariusxz/p/4790268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!