题目大意:
A认识B,B认识C,则为ABC准备一张桌子。即看能把一群人分成几堆。
题解:并查集的应用,看有几个是par[x]=x的,即看有几个根节点就行了。
#include <iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
#define maxn 10000
int par[maxn];
int ranks[maxn];
int N,M;
void Init()
{
for(int i=1;i<=N;i++)
{
par[i]=i;
ranks[i]=0;
}
}
int finds(int x)
{
int t=x;
while(t!=par[t])//递归的等价形式
t=par[t];
par[x]=t;
return t;
}
void unions(int x,int y)
{
int root1,root2;
root1=finds(x);
root2=finds(y);
if(root1!=root2)
{
// par[root1]=root2;//!!!!不是par[x]
if(ranks[root1]<ranks[root2])
par[root1]=root2;
else
{
par[root2]=x;
if(ranks[root1]==ranks[root2])
ranks[root1]++;
}
}
}
int main()
{
int T;
int x,y;
cin>>T;
while(T--)
{
cin>>N>>M;
Init();
while(M--)
{
cin>>x>>y;
unions(x,y);
}
int sum=0;
for(int i=1;i<=N;i++)
{
if(i==par[i])
sum++;
}
cout<<sum<<endl;
}
return 0;
}