https://vjudge.net/problem/HDU-1213
One important rule for this problem is that if I tell you A knows B, and B knows C, that means A, B, C know each other, so they can stay in one table.
For example: If I tell you A knows B, B knows C, and D knows E, so A, B, C can stay in one table, and D, E have to stay in the other one. So Ignatius needs 2 tables at least.
InputThe input starts with an integer T(1<=T<=25) which indicate the number of test cases. Then T test cases follow. Each test case starts with two integers N and M(1<=N,M<=1000). N indicates the number of friends, the friends are marked from 1 to N. Then M lines follow. Each line consists of two integers A and B(A!=B), that means friend A and friend B know each other. There will be a blank line between two cases.
OutputFor each test case, just output how many tables Ignatius needs at least. Do NOT print any blanks.
Sample Input
2 5 3 1 2 2 3 4 5 5 1 2 5
Sample Output
2 4
1 #include<bits/stdc++.h> 2 using namespace std; 3 int parent[1010],ans; 4 int i,j,t,m,n,a,b,f1,f2; 5 int Find(int x) 6 { 7 if(parent[x]!=x)return x=Find(parent[x]); 8 return x; 9 } 10 /* 11 void union_(int x,int y) 12 { 13 if((x=Find(x)==(y=Find(y)))) 14 return; 15 if(parent[x]<parent[y]) 16 { 17 parent[x]+=parent[y]; 18 parent[y]=x; 19 } 20 else 21 { 22 parent[y]+=parent[x]; 23 parent[x]=y; 24 } 25 } 26 */ 27 int main() 28 { 29 cin>>t; 30 for(i=1;i<=t;i++) 31 { 32 ans=0; 33 cin>>m>>n; 34 for(j=1;j<=m;j++) 35 parent[j]=j; 36 for(j=1;j<=n;j++) 37 { 38 cin>>a>>b; 39 f1=Find(a); 40 f2=Find(b); 41 parent[f1]=parent[f2]; 42 } 43 for(j=1;j<=m;j++) 44 if(parent[j]==j) 45 ans++; 46 cout<<ans<<endl; 47 } 48 return 0; 49 }
思路:
思路简单就是查找有多少个不同的联通分量。
注意点:
一开始做这个题还多写了个void union_(int x,int y),被MLE了。后来想了下原因,可能是这个函数在执行的时候进行了多次Find(x),而这个函数是通过递归来实现的,递归的实现要占用内存,所以内存就上去了。后来用一个赋值语句代替了这个函数parent[f1]=parent[f2]; 。因为本题只需要求出不同连通分量的个数,不需要知道一个联通分量里元素的个数,所以没有必要再写原来那个函数了。