这一题是听同学讲过例题后,现在做起来,感觉特别有意思。
rank表示当前点到父节点的距离,如果距离是奇数,那么这两个就是异性,否则是同性,所以可以用%2判定他们之间的性别。以下注释是根据自己的理解写的,其实也不太清楚自己的理解是否是正确的^_^
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "stdio.h"
2 #include "string.h"
3
4 int f[3000];
5 int rank[3000];
6
7 int find(int x)
8 {
9 int t;
10 if(x==f[x])
11 return x;
12
13 t=find(f[x]);
14 rank[x]=(rank[x]+rank[f[x]])%2;//在更新父节点之前要记录该点与要更新的那个点之间的关系
15 f[x]=t;
16 return t;
17 }
18
19 int join(int x,int y)
20 {
21 int a=find(x);
22 int b=find(y);
23
24 if(a==b)
25 {
26 if(rank[x]==rank[y])//两者的父节点相同,而两者与父节点性别的区别是相同的,那么这两个就是同性了,说明存在同性恋^_^
27 return 1;
28 return 0;
29 }
30 f[a]=b;
31 rank[a]=(rank[x]+rank[y]+1)%2;//X与Y是异性,那么a与b是什么关系呢,将X与Y连接起来距离加1,所以将X与a的距离加Y与b的距离再加1^_^
32 return 0;
33 }
34
35 int main()
36 {
37 int cas,c=1;
38 int n,m;
39 int i,flag,a,b;
40 scanf("%d",&cas);
41 while(cas--)
42 {
43 scanf("%d%d",&n,&m);
44 memset(rank,0,sizeof(rank));
45
46 for(i=1;i<=n;i++)
47 {
48 f[i]=i;
49 }
50
51 flag=0;
52 for(i=0;i<m;i++)
53 {
54 scanf("%d%d",&a,&b);
55 if(join(a,b))
56 flag=1;
57 }
58
59 printf("Scenario #%d:\n",c++);
60 if(flag)
61 printf("Suspicious bugs found!\n");
62 else
63 printf("No suspicious bugs found!\n");
64 //if(cas)
65 printf("\n");//看到这些什么一个例子后一个换行符什么的就迷瞪,何必啊O_O!
66 }
67
68 return 0;
69 }
70