标签:注意 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