poj2524(并查集)买一送一hdu1213
已知有n个大学生,其中有m对宗教信仰相同的学生,请你估算这n个学生中最多有多少种宗教信仰。
依旧是简单的并查集应用。宗教信仰的最大值为学生数n,因此一开始把n个学生作为n个集合,对给出的每对大学生 a 和 b ,如果他们在不同的集合,就合并他们,然后宗教数减一。
1 #include <stdio.h> 2 using namespace std; 3 4 int sum; 5 int set[50005]; 6 7 void makeset(int n) 8 { 9 for(int i=1;i<=n;i++) 10 { 11 set[i]=i; 12 } 13 } 14 15 16 int findset(int x)//查 17 { 18 if(x!=set[x]) 19 { 20 set[x]=findset(set[x]);//之所以不可以直接返回是因为这里可能有多层的关系 21 } 22 return set[x]; 23 } 24 void Union(int a,int b)//并 25 { 26 int x=findset(a); 27 int y=findset(b); 28 if(x==y) 29 { 30 return ; 31 } 32 sum--; 33 set[x]=y; 34 35 } 36 int main() 37 { 38 39 int n,m,first,second; 40 int k=1; 41 while(1) 42 { 43 scanf("%d %d",&n,&m); 44 if(n==0&& m==0) break; 45 sum=n; 46 makeset(n); 47 for(int i=0;i<m;i++) 48 { 49 scanf("%d%d",&first,&second); 50 Union(first,second); 51 } 52 printf("Case %d: %d\n",k++,sum); 53 54 } 55 return 0; 56 }
知道思路之后,代码就是十分钟的事
hdu1213
1 #include <stdio.h> 2 using namespace std; 3 4 int sum; 5 int set[1005]; 6 7 void makeset(int n) 8 { 9 for(int i=1;i<=n;i++) 10 { 11 set[i]=i; 12 } 13 } 14 15 16 int findset(int x)//查 17 { 18 if(x!=set[x]) 19 { 20 set[x]=findset(set[x]);//之所以不可以直接返回是因为这里可能有多层的关系 21 } 22 return set[x]; 23 } 24 void Union(int a,int b)//并 25 { 26 int x=findset(a); 27 int y=findset(b); 28 if(x==y) 29 { 30 return ; 31 } 32 sum--; 33 set[x]=y; 34 35 } 36 int main() 37 { 38 39 int n,m,first,second; 40 int Case; 41 scanf("%d",&Case); 42 getchar(); 43 while(Case--) 44 { 45 scanf("%d %d",&n,&m); 46 getchar(); 47 if(n==0&& m==0) break; 48 sum=n; 49 makeset(n); 50 for(int i=0;i<m;i++) 51 { 52 scanf("%d%d",&first,&second); 53 getchar(); 54 Union(first,second); 55 } 56 printf("%d\n",sum); 57 getchar(); 58 } 59 return 0; 60 }
唉……