簡介:
並查集是樹的一種數據結構,用於處理多組不相交際集合之間的間接關係。集
是單元素構成的集合,查
是查找兩兩集合是否有關係,並
就是把有聯繫的集合合併。如擒賊先擒王,把最終的boss找出來。
例題詳細介紹:
題目:
今天是伊格納修斯的生日。他邀請了很多朋友。現在是晚餐時間。伊格納修斯想知道他至少需要多少張桌子。你必須注意到並非所有的朋友都相互認識,所有的朋友都不想和陌生人呆在一起。
這個問題的一個重要規則是,如果我告訴你A知道B,B知道C,那意味着A,B,C彼此瞭解,所以他們可以留在一個表中。
例如:如果我告訴你A知道B,B知道C,D知道E,所以A,B,C可以留在一個表中,D,E必須留在另一個表中。所以Ignatius至少需要2張桌子。
輸入
輸入以整數T(1 <= T <= 25)開始,表示測試用例的數量。然後是T測試案例。每個測試用例以兩個整數N和M開始(1 <= N,M <= 1000)。 N表示朋友的數量,朋友從1到N標記。然後M行跟隨。每一行由兩個整數A和B(A!= B)組成,這意味着朋友A和朋友B彼此瞭解。兩個案例之間會有一個空白行。
產量
對於每個測試用例,只輸出Ignatius至少需要多少個表。不要打印任何空白。
Sample Input
2
5 3
1 2
2 3
4 5
5 1
2 5
Sample Output
2
4
題意:就是如果有聯繫的人可以坐一張桌子上,如果沒有聯繫就單獨一個人坐,一共需要多少張桌子。具體算法代碼介紹:
#include<stdio.h>
int f[51001]={0},n,m;
void init()//初始化表示剛開始自己一個人坐一張桌子,互不影響
{
int i;
for(i=1;i<=n;i++)
f[i]=i;
return;
}
int getf(int v)//這個是找有關係的人,不停去找,直到找到最初始有關係的人,既擒賊先擒王
{
if(f[v]==v)
return v;
else
{
f[v]=getf(f[v]);//遞歸去尋找,壓縮路徑
return f[v];
}
}
void merge(int v,int u)
{
int t1,t2;
t1=getf(v);
t2=getf(u);//t1,t2分別表示v,u的最終有關係的人
if(t1!=t2)
f[t2]=t1;//判斷兩人是否有關係,既並於一個集合
return;
}
int main()
{
int i,x,y,sum;
int cas=1;
int N;
scanf("%d",&N);
while(N--)
{
sum=0;
scanf("%d%d",&n,&m);
init();
for(i=1;i<=m;i++)
{//合併有關係的人
scanf("%d%d",&x,&y);
merge(x,y);
}
for(i=1;i<=n;i++)//最後掃描一共需要多少桌
{
if(f[i]==i)
sum++;
}
printf("%d\n",sum);
}
return 0;
}