K - 歐拉回路(並查集)

點擊打開鏈接


K - 歐拉回路


歐拉回路是指不令筆離開紙面,可畫過圖中每條邊僅一次,且可以回到起點的一條迴路。現給定一個圖,問是否存在歐拉回路?
Input測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是節點數N ( 1 < N < 1000 )和邊數M;隨後的M行對應M條邊,每行給出一對正整數,分別是該條邊直接連通的兩個節點的編號(節點從1到N編號)。當N爲0時輸入結 
束。 Output每個測試用例的輸出佔一行,若歐拉回路存在則輸出1,否則輸出0。 
Sample Input
3 3
1 2
1 3
2 3
3 2
1 2
2 3
0
Sample Output
1
0


歐拉回路及歐拉路徑定義:
若圖G中存在這樣一條路徑,使得它恰通過G中每條邊一次,則稱該路徑爲歐拉路徑。若該路徑是一個圈,則稱爲歐拉(Euler)迴路
判斷方法:
先用 dfs 或並查集判斷圖的連通性,再根據頂點度的性質判斷。
有向圖歐拉回路:所有頂點的入度和出度相等
無向圖歐拉回路:所有頂點的度數爲偶數
有向圖歐拉路徑:所有頂點的入度和出度相等或存在兩個頂點 a、b ,a 的入度比 b 的入度大 1,a 的出度比 b 小 1
無向圖歐拉路徑:所以頂點的度的和爲偶數且至多有兩個頂點的度數爲奇數




Select Code

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

int count=0;
int par[10000];
int aa[1005];
void init(int a)
{
	for(int i=1; i<=a; i++)
	par[i]=i;
}

int find(int x)
{
	if(x==par[x])
	return x;
	else
	return par[x]=find(par[x]);
}

void join(int x, int y)
{
	int count=0;
	int fx=find(x),fy=find(y);
	if(fx!=fy)
	{
		par[fx]=fy;
	}
}
int main()
{
	int count;
	int a,b;
	while(~scanf("%d%d",&a,&b)&&a)
	{
		init(a); 
		int flag=1;
		memset(aa, 0, sizeof(aa));		//清空數組
		for(int i=1; i<=b; i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			aa[x]++ , aa[y]++;			//記錄節點的入度和出度
			join(x,y);
		}
		int sum=0;
		for(int i=0; i<a; i++)
		{
			if(par[i]==i)
			sum++;
			if(aa[i]&1)			//aa[i]%2			flag=0;		}
		if(sum!=1)
		flag = 0;
		printf("%d\n",flag);
	}
	return 0;
}
還可以用dfs來做;





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章