1. Fleury(佛罗莱)算法
设G 为一无向欧拉图,求G 中一条欧拉回路的算法为:
1) 任取G 中一顶点v0,令P0 = v0;
2) 假设沿Pi = v0e1v1e2v2 …eivi 走到顶点vi,按下面方法从E(G) - { e1, e2, …, ei }中选ei+1:
a) ei+1 与vi 相关联;
b) 除非无别的边可供选择,否则ei+1 不应该是Gi = G - { e1, e2, …, ei }中的桥。
3) 当2)不能再进行时算法停止。
可以证明的是,当算法停止时,所得到的简单回路Pm = v0e1v1e2v2 …emvm, (vm = v0)为G 中一条
欧拉回路。
2. 桥
设无向图G(V, E)为连通图,若边集E1⊆E,在图G 中删除E1 中所有的边后得到的子图是不连
通的,而删除了E1 的任一真子集后得到的子图是连通图,则称E1 是G 的一个割边集。若一条边
设G 为一无向欧拉图,求G 中一条欧拉回路的算法为:
1) 任取G 中一顶点v0,令P0 = v0;
2) 假设沿Pi = v0e1v1e2v2 …eivi 走到顶点vi,按下面方法从E(G) - { e1, e2, …, ei }中选ei+1:
a) ei+1 与vi 相关联;
b) 除非无别的边可供选择,否则ei+1 不应该是Gi = G - { e1, e2, …, ei }中的桥。
3) 当2)不能再进行时算法停止。
可以证明的是,当算法停止时,所得到的简单回路Pm = v0e1v1e2v2 …emvm, (vm = v0)为G 中一条
欧拉回路。
2. 桥
设无向图G(V, E)为连通图,若边集E1⊆E,在图G 中删除E1 中所有的边后得到的子图是不连
通的,而删除了E1 的任一真子集后得到的子图是连通图,则称E1 是G 的一个割边集。若一条边
构成一个割边集,则称该边为割边,或桥。
//输出欧拉回路
#include <string.h>
#include <stdio.h>
#define maxn 1050
int n, m;
int edge[maxn][maxn];
struct stack
{
int top, node[maxn];
}s;
void dfs(int x)
{
s.node[++s.top] = x;
for(int i=1; i<=n; i++)
{
if(edge[x][i]>0)
{
edge[x][i] = edge[i][x] = 0;
dfs(i);
break;
}
}
}
void Fleury(int x)
{
int flag;
s.top = 0;
s.node[s.top] = x;
while(s.top>=0)
{
flag = 0;
for(int i=1; i<=n; i++)
{
if(edge[s.node[s.top]][i]>0)
{
flag = 1;
break;
}
}
if(!flag)
{
printf("%d%c", s.node[s.top--], s.top==0?'\n':' ');
}
else
dfs(s.node[s.top--]);
}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
memset(edge, 0, sizeof(edge));
for(int i=0; i<m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
edge[a][b] = edge[b][a] = 1;
}
int num = 0, start = 1;
for(int i=1; i<=n; i++)
{
int deg = 0;
for(int j=1; j<=n; j++)
{
deg += edge[i][j];
}
if(deg%2)
{
start = i;
num++;
}
}
if(num==0||num==2)
Fleury(start);
else
printf("不存在欧拉回路\n");
}
return 0;
}