欧拉回路

来源:互联网 发布:java decimalformat 编辑:程序博客网 时间:2024/05/29 16:41

欧拉回路与欧拉道路

图G的一个回路,若它恰通过G中每条边一次,则称该回路为欧拉(Euler)回路。
如果一个图只是形成一个连通所有节点的链,且每一点只走一次,则成为欧拉道路。
具有欧拉回路或欧拉道路的图称为欧拉图(简称E图)。
有向图的欧拉回路
一个有向图存在欧拉回路的前提条件是这个图是个连通图,其次要求其每个点的入度等于出度,或者其中有一个点的出度比入度大1,另一个点的入度比出度大一这样就存在一条欧拉回路。
如果其每个点的入度等于出度则从任意一点出发,可以走出一条欧拉回路,如果是第二种情况,则必须从出度大于入度 1 的点出发到入度大于出度 1 的点结束,走出一条欧拉道路。
无向图的欧拉回路
跟有向图一样,首先必须连通,其次如果最多只有两个奇点。则满足欧拉回路或欧拉道路,有奇点就从任意一个奇点出发找科形成一条欧拉道路,否则从任意一点出发都能找出欧拉回路。(注意:百度百科上是错的)

如果只是判断一个图是否能够形成欧拉回路的话,就用上面的思路:
首先根据出度跟入度的关系,判断是否满足要求
然后用判断图的连通性可以用并查集或者Dfs如果要求路径的话可以用Dfs

要是需要求出欧拉路径,就用下面这个函数。
下面这个程序,是通过遍历一个图来求其欧拉回路或欧拉道路的。如果需要打印欧拉道路,在主程序中调用,参数必须是道路的起点,另外说明的是,这样打印出来是逆序的,因此在使用的时候,应该用栈压入栈中,还有就是其对无向图和有向图遍历都有用。其实这个算法跟最小生成树prim里面每次求连接上一边最小权值的边算法一样,这个只是那个算法的一个简化。可根据那个进行理解。

#include<iostream>  #include<stack>  const int MAXN=111;  using namespace std;  stack<int>S;  int edge[MAXN][MAXN];  int n,m;  void dfs(int x){      S.push(x);      for(int i=1;i<=n;i++){          if(edge[x][i]>0){              edge[i][x]=edge[x][i]=0;//删除此边              dfs(i);              break;          }      }  }  //Fleury算法的实现  void Fleury(int x){      S.push(x);      while(!S.empty()){          int b=0;          for(int i=1;i<=n;i++){              if(edge[S.top()][i]>0){                  b=1;                  break;              }          }          if(b==0){              printf("%d",S.top());              S.pop();          }else {              int y=S.top();              S.pop();              dfs(y);//如果有,就dfs          }      }      printf("\n");  }  int main(){      scanf("%d%d",&n,&m); //读入顶点数以及边数      memset(edge,0,sizeof(edge));      int x,y;      for(int i=1;i<=m;i++){          scanf("%d%d",&x,&y);          edge[x][y]=edge[y][x]=1;      }      //如果存在奇数顶点,则从奇数顶点出发,否则从顶点0出发      int num=0,start=1;      for(int i=1;i<=n;i++){                        //判断是否存在欧拉回路          int degree=0;          for(int j=1;j<=n;j++){              degree+=edge[i][j];          }          if(degree&1){              start=i,num++;          }      }      if(num==0||num==2){          Fleury(start);      }else          printf("No Euler Path\n");      return 0;  }  
原创粉丝点击