題目描述
cfk爲了慶祝期末考結束,請了很多朋友去吃飯,爲了省錢,cfk希望他需要準備的桌子數儘可能少,但是cfk的朋友和cfk一樣,十分挑剔,他們只和自己的朋友坐在一桌。如果a和b是朋友,b和c是朋友,那麼a和c也是朋友,a,b,c可以坐在一桌,同時d和e也是朋友,但由於d,e與a,b,c不是朋友,所以d,e需要坐在另一張桌子。問cfk最少需要多少桌子。
Input
輸入以一個整數T開始 (1<=T<=25) 表示測試數據組數. 接下來是T個測試數據。 每個測試數據以兩個整數N和M開始(1<=N,M<=1000). N表示cfk邀請的朋友的數目,編號爲1~N。接下來是M行,每行包含兩個整數A和B(A!=B),表示A和B互相是朋友。每兩組測試數據間以一個空行相隔。
Output
對於每組測試數據,輸出一個整數,代表最少需要擺放的桌數。 請不要輸出任何空格。
Sample Input
2
5 3
1 2
2 3
4 5
5 1
2 5
Sample Output
2
4
這就是並查集的一道模板題,並查集主要就是一個尋找祖先的函數,和路徑壓縮。
#include<bits/stdc++.h>
#define N 10100
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e6+10;
int pre[maxn];
int unionserch(int root)
{
int son,temp;
son=root;
while(root!=pre[root])//找祖先
{
root=pre[root];
}
while(son!=root)//路徑壓縮
{
temp=pre[son];
pre[son]=root;
son=temp;
}
return root;
}
int main()
{
ios::sync_with_stdio(false);
int n,m,t,x,y;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
pre[i]=i;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
int bx=unionserch(x);
int by=unionserch(y);
if(bx!=by)
pre[bx]=by;
}
int tol=0;
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
tol++;
}
cout<<tol<<endl;
}
}