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\n");
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\n");
64         else if(num>1)
65             printf("Can not determine\n");
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\n",res,Max);
72         }
73     }
74     return 0;
75 }

原文地址:https://www.cnblogs.com/FrankChen831X/p/10659338.html

时间: 2024-10-08 10:42:24

poj2912(带权并查集+枚举)的相关文章

poj2912 带权并查集

题意:多个人玩石头剪刀布,每个人提前选定了自己出哪个手势,而其中有一种特殊的人他可以随意出什么手势,问是否能够从给出的一系列石头剪刀布游戏中判断出哪个是特殊的,可以从第几局游戏中判断出来. 首先按照食物链那题的做法,定 0,1,2 做为三种手势就可以了,但是这题非常坑,如果在前面的游戏中就能够判断特殊的人了,那么之后的游戏就算有其他矛盾发生也不管了,所以只能找到错就跳出……不过由于判断是哪个人比较麻烦,不知道哪个人的选择是无效的,就不知道那几次游戏是不正确不能加入并查集的,因此就直接暴力枚举每个

并查集练习2(带权并查集)

明天旅游去爬山逛庙玩,今天练一天然后早早睡觉啦~ poj1703 Find them, Catch them (带权并查集) 1 #include<cstdio> 2 const int N=1e5+1; 3 int f[N]; 4 int r[N];//表示与父节点的关系,0同类,1不同类 5 int n; 6 void init(){ 7 for(int i=1;i<=n;++i){ 8 f[i]=i; r[i]=0; 9 } 10 } 11 int fin(int x){ 12 i

Lightoj1009 Back to Underworld(带权并查集)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Back to Underworld Time Limit:4000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Description The Vampires and Lykans are fighting each other to death. The war has become so fierc

HDU 5176 The Experience of Love 带权并查集

The Experience of Love Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) [Problem Description] A girl named Gorwin and a boy named Vivin is a couple. They arrived at a country named LOVE. The country consisting of N

poj 2912(带权并查集)

题意:有n个人玩石头剪刀布的游戏,编号从1到n-1,把所有人分成3组,给每个组分配一个手势(石头.剪子.布),每轮挑出两个人出来进行游戏,这n个人里有一个裁判,他的手势是可以变化的.给出了m轮的游戏结果,a < b表示b赢了a,a = b表示a和b出了同样的手势,问能否找到裁判的编号,是在第几轮发现的. 题解:这题和食物链那个经典带权并查集很像,也可以用0表示父与子是同一种手势,用1表示父大于子,用2表示父小于子.因为裁判的编号不能确定,可以采用枚举的方式,先假定一个人是裁判,然后去掉这个人所有

POJ 1182 食物链 带权并查集

动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之一时,这句话就是假话,否

hdu3038(带权并查集)

题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示从第x,个元素到第y个元素的和为d(包括x, 和y), 问m行输入里面有几个是错误的(第一个输入是正确的); 思路: 很显然带权并查集咯,我们可以用距离的概念代替和的概念比较好理解一点,d表示x到y的和即x到y的距离; 可以用rank[x]表示x到其父亲节点的距离,  将正确的距离关系合并到并查集中

【POJ1182】 食物链 (带权并查集)

Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类. 第二种说法是"2 X Y",表示X吃Y. 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的.当一句话满足下列三条之

【poj 1988】Cube Stacking(图论--带权并查集 模版题)

题意:有N个方块,M个操作{“C x”:查询方块x上的方块数:“M x y”:移动方块x所在的整个方块堆到方块y所在的整个方块堆之上}.输出相应的答案. 解法:带权并查集.每堆方块作为一个集合,维护3个数组:fa[x]表示x方块所在堆的最顶部的方块:d[x]表示x方块所在堆的最底部的方块:f[x]表示x方块方块x上的方块数. 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<