欧拉回路

xiaoxiao2021-02-28  124

欧拉回路与欧拉道路

图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; }
转载请注明原文地址: https://www.6miu.com/read-74495.html

最新回复(0)