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}中的桥。(桥:图中的一条边,若删除则图不连通。
c) 当b不能再进行时,算法停止。
可以证明当算法停止时所得到的简单回路Pm=v0e1v1e2...emvm(vm=v0)为G中的一条欧拉回路,算法复杂度为O(e*e)。
Fleury算法模板:
#include<bits/stdc++.h>
using namespace std;
int n,t,start,top,sum;
int degree[1005],a[1005],m[1005][1005];
void dfs(int x)
{
a[++top]=x;
for(int i=1;i<=n;i++)
{
if(m[x][i])
{
m[x][i]=m[i][x]=0;
dfs(i);
break;
}
}
}
void fleury(int x)
{
top=1;
a[top]=x;
while(top>0)
{
int flag=0;
for(int i=1;i<=n;i++)
{
if(m[a[top]][i])
{
flag=1;
break;
}
}
if(flag==0)
{
cout<<a[top]<<' ';
top--;
}
else
{
top--;//切勿遗漏
dfs(a[top+1]);
}
}
}
int main()
{
while(cin>>n>>t)
{
memset(degree,0,sizeof(degree));
memset(m,0,sizeof(m));
for(int i=1;i<=t;i++)
{
int x,y;
cin>>x>>y;
m[x][y]=m[y][x]=1;
degree[x]++;
degree[y]++;
}
start=1; //若有奇度点则从该店开始搜索,若所有点度数全为偶数那就从1开始搜
sum=0;
for(int i=1;i<=n;i++)
{
if(degree[i]%2==1)
{
sum++;
start=i;//若有奇度点,奇度点一定为开始点或结束点
}
}
if(sum==0||sum==2) fleury(start);//连通图的奇度点只有两个,能构成回路的图是不存在奇度点的;
else cout<<"NO Euler path"<<endl;
cout<<endl;
}
return 0;
}