fleury算法输出欧拉回路

来源:互联网 发布:淘宝美工助理注册码 编辑:程序博客网 时间:2024/06/05 03:23
1、定义:
欧拉通路(回路):通过图(无向图或有向图)中所有一次且仅一次行遍图中所有顶点的
    通路(回路)称为欧拉通路(回路)。
欧拉图与半欧拉图:具有欧拉回路的图称为欧拉图,具有欧拉通路而无欧拉回路的
    图称为半欧拉图。
:设无向图G=<V,E>,若存在边集E的一个非空子集E1,使得p(G-E1)>p(G),而对
    于E1的任意真子集E2,均有p(G-E2)=p(G),则称E1是G的边割集,或简称割集;
    若E1是单元集,即E1={e},则称e为割边或。[p(G)表示图G的连通分支数.]
 
2、定理:
<无向图>
定理1:无向图G是欧拉图当且仅当G是连通图,且G中没有奇度顶点。
定理2:无向图G是半欧拉图当且仅当G是连通图,且G中恰有两个奇度顶点。
 
<有向图>
定理1:有向图D是欧拉图当且仅当D是强连通的且每个顶点的入度都等于出度。
定理2:有向图D是半欧拉图当且仅当D是单向连通的,且D中恰有两个奇度顶点,其
       中一个入度比出度大1,另一个的出度比入度大1,而其余顶点的入度都等于
       出度。
 
3、求欧拉回路的Fleury算法:
   设G为欧拉图,一般说来G中存在若干条欧拉回路,下面是求欧拉回路的Fleury算法:
Fleury算法:
(1)任取v0∈V(G),令P0=v0;
(2)设Pi=v0e1v1e2...eivi已经行遍,按下面方法来从E(G)-{e1,e2,...,ei}中选
     取ei+1:
    (a)ei+1与vi想关联;
    (b)除非无别的边可供行遍,否则ei+1不应该为Gi=G-{e1,e2,...,ei}中的桥.
(3)当(2)不能再进行时,算法停止。

可以证明,当算法停止时所得简单回路Pm=v0e1v1e2...emvm(vm=v0)为G中的一条欧拉回路




#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<stack>using namespace std;stack<int>que;int a[1000][1000];int n,m;void dfs(int x){    int i;    que.push(x);    for(i=1;i<=n;i++)    {        if(a[x][i]>0)        {            a[x][i]=0;            a[i][x]=0;            dfs(i);            break;        }    }}void fleury(int x){    int i,j;    int b;    que.push(x);    while(!que.empty())    {        b=0;        for(i=1;i<=n;i++)        {            if(a[que.top()][i]>0)            {                b=1;                break;            }        }        if(b==0)        {            printf("%d ",que.top());            que.pop();        }        else        {            int y=que.top();            que.pop();            dfs(y);        }    }    printf("\n");    return ;}int main(){    int i,j,p,q;    while(scanf("%d %d",&n,&m)!=EOF)    {        memset(a,0,sizeof(a));            for(j=1;j<=m;j++)            {                scanf("%d %d",&p,&q);                a[p][q]=a[q][p]=1;            }        int num=0;        int start=1;        int degree=0;        for(i=1;i<=n;i++)        {            degree=0;            for(j=1;j<=n;j++)            {                degree+=a[i][j];            }            if(degree%2==1)            {                start=i;                num++;            }        }        if(num==0||num==2)        {            fleury(start);        }        else        {            printf("NO Eular path\n");        }        while(!que.empty())        {            que.pop();        }    }    return 0;}



原创粉丝点击