Description
小明过生日邀请了n位朋友来做客,这些朋友中m对相互认识,他们可以做同一张桌子,但如果一个人和一张桌子上坐着的所有人都不认识,那么他不会坐这张桌子,问小明至少需要准备多少张桌子
Input
第一行一个整数T表示用例组数,每组用例第一行为两个整数n和m分别表示人数和相互认识的朋友对数,之后m行每行两个整数a和b表示a和b相互认识(1<=n,m<=1000)
Output
输出小明最少需要准备多少张桌子
Sample Input
2
5 3
1 2
2 3
4 5
5 1
2 5
Sample Output
2
4
Solution
并查集,每个人初始都是一个集合,对于认识的两个人,合并其所处的集合,最后统计不同集合个数即可
Code
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define maxn 1111
int par[maxn];
int deep[maxn];
void init(int n)
{
for(int i=0;i<n;i++)
{
par[i]=i;
deep[i]=0;
}
}
int find(int x)
{
if(par[x]==x) return x;
else return par[x]=find(par[x]);
}
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y) return;
if(deep[x]<deep[y]) par[x]=y;
else
{
par[y]=x;
if(deep[x]==deep[y]) deep[x]++;
}
}
int main()
{
int T,n,m,x,y,ans;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init(n+1);
while(m--)
{
scanf("%d%d",&x,&y);
unite(x,y);
}
ans=0;
for(int i=1;i<=n;i++)
if(i==par[i])ans++;
printf("%d\n",ans);
}
return 0;
}