Fleury算法求欧拉回路/欧拉路径

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;  
}  

猜你喜欢

转载自blog.csdn.net/qq_37016724/article/details/80586442