1. 程式人生 > >HDU:1878 歐拉回路(並查集+歐拉回路)

HDU:1878 歐拉回路(並查集+歐拉回路)

1 0

題義就是在給定的圖中判定是否存在歐拉回路。

圖G的一個迴路,若它恰通過G中每條邊一次,則稱該回路為尤拉(Euler)迴路。
具有歐拉回路的圖稱為尤拉圖(簡稱E圖)。

這裡總結下各種圖的判定的方法:

1.無向圖中:所給定的圖為連通圖,且所有節點的度為偶數;
2.有向圖中:所給定的圖為連通圖,且所有節點的度為零。

所以對於該題,只需用並查集將節點連線,判斷連通(即生成一棵樹),再判斷所有節點的度數是否都為偶數即可。
#include <stdio.h>
#include <string.h>
int cnt[1001];
int pre[1001];
int find(int x)
{
	int r=x;
	while(r!=pre[r])
	{
		r=pre[r];
	}
	return r;
}
int main()
{
	int n,m;
	while(scanf("%d",&n)!=EOF)
	{
		if(n==0)
		break;
		memset(cnt,0,sizeof(cnt));
		for(int i=1;i<=n;i++)
		{
			pre[i]=i;
		}
		scanf("%d",&m);
		while(m--)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			cnt[a]++;
			cnt[b]++;
			int fx=find(a);
			int fy=find(b);
			if(fx!=fy)
			{
				pre[fx]=fy;
			}
		}
		int root=0;
		int du=0;
		for(int i=1;i<=n;i++)
		{
			if(cnt[i]%2==0)
			{
				du++;
			}
			if(i==pre[i])
			{
				root++;
			}
		}
		if(du==n&&root==1)
		{
			printf("1\n");
		}
		else
		{
			printf("0\n");
		}
	}
	return 0;
}


用深搜也能做:

#include<iostream>
using namespace std;
#define N 1001
int map[N][N];
bool visited[N];
int cheak[N];
int n,i;
void init()
{
	memset(visited,0,sizeof(visited));
	memset(map,0,sizeof(map));
	memset(cheak,0,sizeof(cheak));

}
void DFS(int k)
{
	visited[k]=1;
	for(i=1;i<=n;i++)
		if(!visited[i]&&map[k][i])
	    	DFS(i);
		
		return;
}
int  cheakk()
{
	for(i=1;i<=n;i++)
		if(cheak[i]%2)
			return 0;

		return 1;
}
int main()
{
	int m,i,a,b;
	while(cin>>n&&n)
	{
		cin>>m;
		init();

		for(i=1;i<=m;i++)
		{  
			scanf("%d%d",&a,&b);
			map[a][b]=map[b][a]=1;

			cheak[a]++;
			cheak[b]++;

		}

		DFS(1);

		for(i=1;i<=n;i++)
			if(!visited[i])
				break;

		if(i>n&&cheakk())
			printf("1\n");
		else
			printf("0\n");
	}
	return 0;
}