欧拉回路的判定(Fleury算法)

来源:互联网 发布:音视频分离软件 编辑:程序博客网 时间:2024/05/16 08:20

定理:

(一)一个图有欧拉回路当且仅当它是连通的且每个顶点都有偶数度。

(二)一个图有欧拉通路当且经当它是连通的且除两个顶点外,其他顶点都有偶数度。

在第二个定理下,含奇数度的两个节点中,一个必为欧拉通路起点,另一个必为欧拉通路的终点。

设G是一个无向的欧拉图,求G中的一条欧拉回路的算法为:

(1)任意选取G中的一个点V0,令P0 = V0。

(2)假设沿pi = v0e1v1e2v2......eivi走到了点vi,按照下面的方法从E - {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中的一条欧拉回路。





#include <iostream>#include <cstdio>#include <fstream>#include <algorithm>#include <cmath>#include <deque>#include <vector>#include <list>#include <queue>#include <string>#include <cstring>#include <map>#define PI acos(-1.0)#define mem(a,b) memset(a,b,sizeof(a))#define sca(a) scanf("%d",&a)#define pri(a) printf("%d\n",a)#define M 202#define INF 100000001using namespace std;typedef long long ll;struct stack{    int top,node[M];}s;int e[M][M],n;void dfs(int x){    int i;    s.node[++s.top]=x;    //cout<<s.top<<' '<<s.node[s.top]+1<<endl;    for(i=0;i<n;i++)    {        if(e[i][x]>0)        {            e[i][x]=e[x][i]=0;  //删除这条边            dfs(i);            break;        }    }}void fleury(int x){    int i,flag;    s.top=0; s.node[s.top]=x;    while(s.top>=0)    {        flag=0;        for(i=0;i<n;i++)        {            if(e[s.node[s.top]][i]>0)            {                flag=1;                break;            }        }        if(!flag) printf("%d ",s.node[s.top--]+1);        else dfs(s.node[s.top--]);    }    puts("");}int main( ){    int i,j,u,v,m,degree,num=0,start=0;    scanf("%d%d",&n,&m);    mem(e,0);    for(i=0;i<m;i++)    {        scanf("%d%d",&u,&v);        e[u-1][v-1]=e[v-1][u-1]=1;    }    for(i=0;i<n;i++)    {        degree=0;        for(j=0;j<n;j++)            degree+=e[i][j];        if(degree&1)        {            start=i;            num++;        }    }    if(num==0||num==2) fleury(start);    else printf("No Euler path\n");    return 0;}

#include <iostream>#include <cstring>#include <vector>using namespace std;const int MAX = 10240;int N, M, pCnt[MAX];int pMap[MAX][MAX];vector<int> pVec;void Search(int x);void Euler_Circuit();int main(){cin >> N >> M;memset(pMap, 0, sizeof(pMap));for(int i = 1; i <= M; i++){int s, e;cin >> s >> e;pMap[s][e] = pMap[e][s] = 1;// 无向图}Euler_Circuit();return 0;}void Euler_Circuit(){int nStart = 1, nOddNum = 0;// nStart保存起点,nOddNum保存有几个顶点有奇数度memset(pCnt, 0, sizeof(pCnt));for(int i = 1; i <= N; i++){for(int j = 1; j <= N; j++){pCnt[i] += pMap[i][j];// 计算各个顶点的度}}for(int i = 1; i <= N; i++)// 统计奇数度顶点的个数{if(pCnt[i] & 1){nStart = i;nOddNum++;}}if(nOddNum > 2 || nOddNum == 1)// 不存在欧拉回路{cout << "Not Exsit Euler Circuit" << endl;}else{Search(nStart);for(int i = 0; i < pVec.size(); i++){ cout << pVec[i] << " "; }cout << endl;}}void Search(int x){for(int i = 1; i <= N; i++){if(pMap[x][i] == 1){pMap[x][i] = pMap[i][x] = 0;// 删边Search(i);}}pVec.push_back(x);}


0 0
原创粉丝点击