HDU 1878 欧拉回路(并查集:简单欧拉回路判定)

欧拉回路

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18877    Accepted Submission(s): 7350


 

Problem Description

欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?

 

 

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

 

 

Author

ZJU

 

 

Source

浙大计算机研究生复试上机考试-2008年

 

 

Recommend

We have carefully selected several similar problems for you:  1879 1880 1877 1881 1863 

 

 

分析:

模板题:

1.图联通(并查集)

2.均为偶数度

 

#include 
#include 
#define N 1000
 
using namespace std;
 
int n, m;
int f[N],degree[N];//记录第i点的度数
 
void init()
{
	for (int i = 1; i <= n; i++)
		f[i] = i;
}
int find(int x)
{
	return x == f[x] ? x : f[x] = find(f[x]);
}
void merge(int x, int y)
{
	int t1, t2;
	t1 = find(x); t2 = find(y);
	if (t1 != t2)	f[t2] = t1;
	else return;
}
int isEuler()
{
	for (int i = 1; i <= n; i++)
		if (degree[i] & 1)	return 0;
	return 1;
}
int isconnect()
{
	int cnt = 0;
	for (int i = 1; i <= n; i++)
	{
		if (f[i] == i)
			cnt++;
	}
	if (cnt == 1)	return 1;
	else return 0;
}
int main()
{
	while (scanf("%d", &n) != EOF && n)
	{
		init();
		memset(degree, 0, sizeof(degree));
		scanf("%d", &m);
		int t1, t2;
		for (int i = 0; i < m; i++)
		{
			scanf("%d%d", &t1, &t2);
			//输入有t1,t2相等的情况
			if (t1 == t2)
				continue;
			degree[t1]++; degree[t2]++;
			merge(t1, t2);
		}
		printf("%d\n", isEuler() && isconnect());
	}
	return 0;
}

 

你可能感兴趣的:(图论——欧拉图)