Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 29548 Accepted Submission(s):
14610
1 #include <stdio.h> 2 int p[1005]; 3 int find(int x) //这个的作用就是下面的查找。 4 { 5 if(x!=p[x]) 6 p[x]=find(p[x]); 7 return p[x]; 8 } 9 int hebing(int x,int y) //这个的作用就是用来合并的。 10 { 11 return p[x]=y; //假设a=2,b=3,此时应该有p[2]=p[3]=3。即2和3到同一张桌子了。 12 } 13 int main() 14 { 15 int t,i,a,b; 16 scanf("%d",&t); 17 while(t--) 18 { 19 int n,m,ans=0; 20 scanf("%d%d",&n,&m); 21 for(i=1;i<=n;i++) 22 p[i]=i; //初始化它,让编号为一的值为1,编号为2的值为2.以此类推。 23 for(i=1;i<=m;i++) 24 { 25 scanf("%d%d",&a,&b); 26 a=find(a); 27 b=find(b); //假设a=2,b=3,我认为经过这个查找之后p[2]就等于p[3]了。 28 if(a!=b) 29 hebing(a,b); //合并为一个值。 30 } 31 for(i=1;i<=n;i++) 32 { 33 if(p[i]==i) //经过M次合并之后,如果是朋友,或者间接朋友的,他们对应的值都为同一个。所以桌子就减少了。 34 ans++; //如果值还是对应的,那么就不是朋友关系,增加一张桌子。 35 } 36 printf("%d\n",ans);//输出注意格式,只有一个空行。 37 } 38 return 0; 39 }
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 52520 Accepted Submission(s):
27993
1 #include<iostream> 2 using namespace std; 3 int p[1000]; 4 int fun1(int x) 5 { 6 if(x!=p[x]) 7 p[x]=fun1(p[x]); 8 return p[x]; 9 } 10 int fun2(int x,int y) 11 { 12 return p[x]=y; 13 } 14 int main() 15 { 16 int n,m,a,b,ans; 17 while(scanf("%d%d",&n,&m)!=EOF&&n!=0) 18 { 19 ans=0; 20 for(int i=1;i<=n;i++) 21 p[i]=i; 22 for(int i=1;i<=m;i++) 23 { 24 scanf("%d%d",&a,&b); 25 a=fun1(a); 26 b=fun1(b); 27 if(a!=b) 28 fun2(a,b); 29 30 } 31 for(int i=1;i<=n;i++) 32 { 33 if(p[i]==i) 34 ans++; 35 } 36 printf("%d\n",ans-1); 37 } 38 return 0; 39 }
总结:此类题的关键是对各个有关数对建立联系,组成数集,然后找出数集个数。
原文:http://www.cnblogs.com/2016024291-/p/6730132.html