並查集算法

簡介:

並查集是樹的一種數據結構,用於處理多組不相交際集合之間的間接關係。是單元素構成的集合,是查找兩兩集合是否有關係,就是把有聯繫的集合合併。如擒賊先擒王,把最終的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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章