View Code
1 /************************************************************/
2 //并查集的应用推广//POJ2492
3 /************************************************************/
4
5 #include<iostream>
6 usingnamespace std;
7 // r[i] 0代表r[i]与i同性, 1代表i与r[i]异性
8 int n,p[2002],r[2002];
9
10 /************************************************************/
11 int find(int x){
12 int temp=p[x];
13 if(x==p[x])return x;
14
15 p[x]=find(p[x]);
16 //首先要明白一点,程序已经从递归中跳出,p[x]已经修改到
17 //根节点,也就是说x已经指向祖先,所以要寻找x与祖先的关系
18
19 //关系修改的解释:根据递归的堆栈原理,可知,x的父亲与
20 //祖先的关系(即r[temp])已经清楚(后进先出),而x与
21 //父亲的关系也是知道的,那么类似于“关系传递”,便可分
22 //析出x与祖先的关系
23 r[x]=(r[temp]==r[x]?0:1);
24 return p[x];
25 }
26
27 /************************************************************/
28
29 void make(){//初始化
30 for(int i = 0;i<=n;i++){
31 p[i]=i;
32 r[i]=0;
33 }
34 }
35
36 /************************************************************/
37
38 void unionSet(int x,int y,int px,int py){
39 p[py]=px;
40 //关系修改解释:
41 //有一点要清楚,由题意知,x与y是异性的,那么
42 //x与x父亲的关系知道,y与与父亲的关系也知道
43 //求x父亲与y父亲关系便显而易见了
44 r[py]=r[x]==r[y] ? 1 : 0;
45 }
46
47 /************************************************************/
48
49 int main(){
50 int i,j,m,a,b,px,py,flag,count=1,t;
51 scanf("%d",&t);
52 while(t--){
53 flag=0;
54 scanf("%d%d",&n,&m);
55 make();
56 while(m--){
57 scanf("%d%d",&a,&b);//由题意知,每输如的一对肯定是异性
58 px=find(a);
59 py=find(b);
60 //如果px==py说明在前面的论断中x与y已经建立起了练习
61 //而现在要通过r[a]是否等于r[b]来验证是否产生了矛盾
62 if(px==py&&r[a]==r[b])
63 flag=1;
64 else
65 unionSet(a,b,px,py);
66 }
67 if(flag==1)
68 printf("Scenario #%d:\nSuspicious bugs found!\n",count++);
69 else
70 printf("Scenario #%d:\nNo suspicious bugs found!\n",count++);
71 printf("\n");
72 }
73 return0;
74 }
http://poj.org/problem?id=2492
posted on 2011-04-26 22:31  geeker  阅读(419)  评论(0编辑  收藏  举报