首页 > 代码库 > 卿学姐与诡异村庄(并查集)
卿学姐与诡异村庄(并查集)
日复一日,年复一年,春去秋来。
卿学姐终于从天行廖那里毕业啦。出山的卿学姐首先来到了一个诡异的村庄。
在这个村庄中,只有两种人,一种是好人,一种是坏人。
好人只说真话,坏人只说假话。
村庄虚伪的平静由于卿学姐的到来,终于被打破了。
人们开始互相指控,每个人都会说另外一个人是否是好人。
卿学姐修行途中只学会了膜法,却不谙世事,所以卿学姐无法确认哪些人是好人,哪些人是坏人。
但是机智的卿学姐意识到可以通过这些人的指控来分辨。
现在告诉你村庄中每个人指控谁是否为好人,请问是否有个合理的分类能够符合所有的指控。
Input
第一行一个整数N,表示村庄总共有N个人,村民从1开始编号到N
1≤N≤100000
接下来N行,每行两个整数 ai,t,如果t是1,那么说明第i个人认为第ai个人是好人。如果t是2,那么说明第i个人认为第ai个人是坏人。
1≤ai≤N
Output
如果存在一个好人坏人的分类能够满足所有的指控,那么输出"Time to show my power”,否则输出"One face meng bi”
Sample Input
32 23 11 2
32 23 21 2
Sample Output
Time to show my power
One face meng bi
Hint
第一组样例中,如果1是好人,2和3都是坏人,就能解释得通这些指控
//非常强,竟然用并查集完美的解决了这个问题,有两个并查集,就是将每个人说的话,当做真话处理,也当做假话处理,两个并查集最后若没有相交部分则成立,也就是,每个人的话都不会自相矛盾,则成立
http://blog.csdn.net/zsc2014030403015/article/details/51255172
但是,这种做法只在这种特定的时候才管用,如果一个人说了多句话呢,或者问你谁是好人,谁是坏人呢?还是很难哪,这种题。。。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MX 100005 4 #define has 100000 5 int n; 6 int f[MX*2]; 7 8 int find_(int x) 9 {10 if (x!=f[x])11 f[x]=find_(f[x]);12 return f[x];13 }14 int join(int a,int b)15 {16 int x=find_(a),y=find_(b);17 if (x!=y)18 f[x]=f[y];19 }20 21 int main()22 {23 while (scanf("%d",&n)!=EOF)24 {25 for (int i=1;i<=n;i++) f[i]=i;26 for (int i=has+1;i<=has+n;i++) f[i]=i;27 for (int i=1;i<=n;i++)28 {29 int x,k;30 scanf("%d%d",&x,&k);31 if (k==1)32 {33 join(i,x);34 join(has+i,has+x);35 }36 if (k==2)37 {38 join(i,has+x);39 join(has+i,x);40 }41 }42 int ok=1;43 for (int i=1;i<=n;i++)44 {45 if (find_(i)==find_(has+i))46 {47 ok=0;48 break;49 }50 }51 if (ok)52 printf("Time to show my power\n");53 else54 printf("One face meng bi\n");55 }56 return 0;57 }
卿学姐与诡异村庄(并查集)