图中所有边一次仅且一次行便所有顶点的通路称作欧拉通路。
图中所有边一次仅且一次行便所有顶点的回路称作欧拉回路。
判断无向图G存在欧拉通路:
G为连通图,并且G仅有两个奇度顶点(度数为奇数的顶点)或者无奇度顶点。
(1)G仅有两个奇度顶点时,G的欧拉通路以此两个结点为端点。
(2)G无奇度顶点时,G必有欧拉回路。
判断有向图D存在欧拉通路:
D为连通图,
(1)图D除两个顶点外,其余顶点的出度与入度都相等。特殊的两点一个顶点的出度与入度之差为1(始点),另一个顶点的出度与入度之差为-1(终点),D为欧拉通路。
(2)D的所有顶点的出、入度都相等时,D中存在欧拉回路。
方法求解:
1、DFS暴搜
例题 The Necklace UVA - 10054
数据:
Sample Input
2
5
1 2
2 3
3 4
4 5
5 6
5
2 1
2 2
3 4
3 1
2 4
Sample Output
Case #1
some beads may be lost
Case #2
2 1
1 3
3 4
4 2
2 2
#include <bits/stdc++.h>
using namespace std;
const int maxn=55;
int Max=-9999, Min=9999;
int ma[maxn][maxn];
int m, n, k=0;
int in[maxn];
int ans[100005][2];
void dfs(int x)
{
int i;
for(i=Min; i<=Max; i++)
{
if(ma[x][i]!=0)//从任意一个与它相连的边出发
{
// cout<<x<<" "<<i<<endl;
ma[x][i]--;
ma[i][x]--;//删除遍历完的边
dfs(i);
ans[++k][0]=x;//记录路径
ans[k][1]=i;
}
}
}
int main()
{
int T;
scanf("%d",&T);
for(int p=1; p<=T; p++)
{
int n;
k=0;
Max=-9999;
Min=9999;//初始化
scanf("%d",&n);
memset(ma, 0, sizeof(ma));
memset(in, 0, sizeof(in));
memset(ans, 0, sizeof(ans));//初始化
for(int i=0; i<n; i++)
{
int x, y;
scanf("%d %d",&x, &y);
ma[x][y]++;
ma[y][x]++;
Max=max(Max, max(x, y));
Min=min(Min, min(x, y));
in[x]++;
in[y]++;
}
int flag=1;
for(int i=Min; i<=Max; i++)//从数据中的最小值到最大值
{
if(in[i]%2==1)//若存在奇点则不是欧拉回路
{
flag=0;
break;
}
}
if(flag)
{
dfs(Min);
}
if(k!=n) flag=0;//若图没有走完说明不是连通图
printf("Case #%d\n",p);
if(flag==0)
printf("some beads may be lost\n");
else
{
for(int i=k; i>=1; i--)
{
printf("%d %d\n",ans[i][0],ans[i][1]);
}
}
if(p!=T)
printf("\n");
}
return 0;
}