标签:注意 test tput 路径 iss img orm each lin
| Time Limit: 10000MS | Memory Limit: 65536K | |
| Total Submissions: 35756 | Accepted: 11730 |
Description
Input
Output
Sample Input
2 3 3 1 2 2 3 1 3 4 2 1 2 3 4
Sample Output
Scenario #1: Suspicious bugs found! Scenario #2: No suspicious bugs found!
Hint
Source
1 /*关于并查集,注意两个概念:按秩合并、路径压缩。
2 1、按秩合并
3 由于并查集一般是用比较高效的树形结构来表示的,按秩合并的目的就是防止产生退化的树(也就是类似链表的树),
4 用一个数组记录各个元素的高度(也有的记录各个元素的孩子的数目,具体看哪种能给解题带来方便),
5 然后在合并的时候把高度小的嫁接到高度大的上面,从而防止产生退化的树。
6 2、路径压缩
7 而另一个数组记录各个元素的祖先,这样就防止一步步地递归查找父亲从而损失的时间。因为并查集只要搞清楚各个元素所在的集合,
8 而区分不同的集合我们用的是代表元素(也就是树根),所以对于每个元素我们只需保存其祖先,从而区分不同的集合。
9 而我们这道题并没有使用纯正的并查集算法,而是对其进行了扩展,
10 我们并没有使用“1、按秩合并”(当然你可以用,那样就需要再开一个数组)
11 我们从“1、按秩合并”得到启示,保存“秩”的数组保存的是 元素相对于父节点的关系 ,我们岂不可以利用这种关系
12 (即相对于父节点的不同秩值来区分不同的集合),从而可以把两个集合合并成一个集合。
13 (注:此代码 relation=0 代表 和父节点同一性别)
14 */
15
16
17 #include<stdio.h>
18 int father[2005];
19 int relation[2005];
20
21 int find_father(int i)
22 {
23 int t;
24 if(father[i]==i)
25 return i;
26
27 //计算相对于新的父节点(即根)的秩,relation[t]是老的父节点相对于新的父节点(即根)的秩,relation[i]是i元素相对于老的父节点的秩,
28 //类似于物理里的相对运动,得到的r[i]就是相对于新的父节点(即根)的秩。而且这个递归调用不会超过两层
29 t=father[i];
30 father[i]=find_father(father[i]);
31 relation[i]=(relation[i]+relation[t]+1)%2; //注意递归中把这棵树relation中的的值都更新一遍,这句的顺序 不能 和上一句 调换位置
32 // relation[a]的改变是伴随着father[a]的改变而更新的(有father改变就有relation改变),要是father改变了,而relation未改变,此时的relation就记录了一个错误的值,
33 //father未改变(即使实际的father已不是现在的值,但只要father未改变,relation的值就是“正确”的,认识到这点很重要。)
34 return father[i];
35 }
36
37 void merge(int a,int b)
38 {
39 int x,y;
40 x=find_father(a);
41 y=find_father(b);
42 father[x]=y;
43 relation[x]=(relation[b]-relation[a])%2;//relation[a]+relation[x]与relation[b]相对于新的父节点必须相差1个等级,因为他们不是gay
44 } //x下边的节点不用改,因为查找的时候会自动更新
45
46 int main()
47 {
48 int T,m,n,i,j,a,b,flag;
49 scanf("%d",&T);
50 for(i=1;i<=T;++i)
51 {
52 flag=0;
53 scanf("%d%d",&n,&m);
54 for(j=1;j<=n;++j) //初始化
55 {
56 father[j]=j;
57 relation[j]=1;
58 }
59 for(j=1;j<=m;++j)
60 {
61 scanf("%d%d",&a,&b);
62 if(find_father(a)==find_father(b))
63 {
64 // if(relation[a]!=(relation[b]+1)%2)
65 if(relation[a]==relation[b]) //说明是同性
66 flag=1;
67 }
68 else
69 merge(a,b);
70 }
71 if(flag)
72 printf("Scenario #%d:\nSuspicious bugs found!\n\n",i);
73 else
74 printf("Scenario #%d:\nNo suspicious bugs found!\n\n",i);
75 }
76 return 0;
77 }
标签:注意 test tput 路径 iss img orm each lin
原文地址:http://www.cnblogs.com/yechanglv/p/6941938.html