HDU1878欧拉回路

欧拉回路

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


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
 

分析:输入2个点的时候记录点的深度,若有点的度不是偶数,则必然不能构成欧拉回路,在度数均为偶数的条件下,可用并查集或DFS来判断。

并查集:对于每次输入的2个点合并,最后若所有的点均在一个集合中则可构成欧拉回路。

实现代码:

//************************************************************************//
//*Author : Handsome How                                                 *//
//************************************************************************//
//#pragma comment(linker, "/STA	CK:1024000000,1024000000")
#pragma warning(disable:4996) 
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <complex>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>                                                
#include <cassert>
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
typedef long long LL;
const int maxn = 1005;
int deep[maxn];
int fat[maxn];
int findf(int x) 
{
	int t = x;
	while (t!=fat[t])
		t = fat[t];
	int c = x,v;
	while (c!=t)
	{
		v = fat[c];
		fat[c] = t;
		c = v;
	}
	return t;
}
void add(int a, int b) {
	a = findf(a);
	b = findf(b);
	if (a == b)return;
	fat[a] = b;
}
int main()
{
	//freopen("E:\\data.in", "r", stdin);
	int n, m;
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0)break;
		bool ok = true;
		int node = 0;
		memset(deep, 0, sizeof(deep));
		fur(i, 1, n)fat[i] = i;
		scanf("%d", &m);
		int a, b;
		while (m--)
		{
			scanf("%d%d", &a,&b);
			deep[a]++; deep[b]++;
			add(a, b);
		}
		fur(i, 1, n)
		{
			if (deep[i] % 2 != 0) { ok = false; break; }
			if (fat[i] == i)node++;
		}
		if (node != 1)ok = false;
		if (ok)printf("1\n");
		else printf("0\n");
	}
	return 0;
}

DFS:首先判断深度,若满足条件则从1开始DFS,然后用一个二维数组记录路径(因为是无向图,所以对线段a-b需要同时记录b-a),接着直接DFS即可。

实现代码:

//************************************************************************//
//*Author : Handsome How                                                 *//
//************************************************************************//
//#pragma comment(linker, "/STA	CK:1024000000,1024000000")
#pragma warning(disable:4996) 
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <complex>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>                                                
#include <cassert>
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
typedef long long LL;
const int maxn = 1111;
int dep[maxn];
int has[maxn][maxn];
int n, m;
bool dfs(int deep,int head)
{
	if (deep == m + 1)return true;
	for (int i = 1; i <=n; i++)
		if (has[head][i])
		{
			has[head][i]--;
			if (dfs(deep + 1, i))return true;
			has[head][i]++;
		}
	return false;
}
int main()
{
	//freopen("E:\\data.in", "r", stdin);
	while (scanf("%d", &n) != EOF)
	{
		if (n == 0)break;
		bool ok = true;
		memset(dep, 0, sizeof(dep));
		memset(has, 0, sizeof(has));
		scanf("%d", &m);
		int a, b;
		int c = m;
		while (c--)
		{
			scanf("%d%d", &a,&b);
			dep[a]++; dep[b]++;
			has[a][b]++; has[b][a]++;
		}
		fur(i, 1, n)if (dep[i] % 2 != 0) { ok = false; break; }
		if (!ok) { printf("0\n"); continue; }
		if (dfs(1,1))printf("1\n");
		else printf("0\n");
	}	
	return 0;
}

后记:DFS所用时间为并查集2倍多,内存为4倍多,故对一些时间要求较高的题目首先推荐并查集。


你可能感兴趣的:(HDU1878欧拉回路)