其他分享
首页 > 其他分享> > 欧拉回路

欧拉回路

作者:互联网

七桥问题

定义 如果图G(有向图或者无向图)中所有边一次仅且一次性遍所有顶点的通路称作欧拉通路。 如果图G中所有边一次仅且一次行遍所有顶点的回路称作欧拉回路。 具有欧拉回路的图称为欧拉图(简称E图)。具有欧拉通路但不具有欧拉回路的图称为半欧拉图。欧拉图上的欧拉路径一定是回路 判断 首先是个连通图

如果所有的点的度数都为偶数,那么这是一条欧拉回路

如果存在两个奇度点,那么从一个奇度点出发,最后到达另一个奇点,则称这是一条欧拉道路。

无向图存在欧拉回路的充要条件:
一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。

有向图存在欧拉回路的充要条件:
一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。

无向图半欧拉图判定

判断:有且仅有两个点度数是奇数

方法:加一条边,找欧拉回路,再删这条边,就找到了欧拉路径

有向图半欧拉图判定

判断:(起点)一个顶点的出度比入度大1,(终点)一个顶点的入度比出度大1,其余顶点入度等于出度

方法:加一条边,找欧拉回路,再删这条边,就找到了欧拉路径

回路的合并

两条回路有交点,可以合并成一条回路

例子:1—>2—>3—>7—>1 & 3—>4—>5—>6—>3

可以想象三自己走到自己  1—>2—>3—>3—>7—>1然后带入第二条回路

合并成功1—>2—>3—>4—>5—>6—>7—>1  

欧拉回路的求解

找到剩余的度数不为0的一点

Hierholzer算法

Hierholzer算法是通过不断从图中删去回路的方式,将删去的多个回路和路径最终组合起来成为欧拉回路或欧拉路径。
算法流程如下:
DFS(x){
枚举与x关联的每条边e
删去e (若是无向图还需 删去对应的反向边)
DFS(e.to)

}将x放入栈中

对于无向图,若无奇点则任意从一个点开始执行算法,若恰有两个奇点则从其中一个开始执行算法
对于有向图,若所有点的入度等于出度则从任意一点开始执行算法, 若恰有两个点入度和出度之差等于1则从其中一个开始执行算法

该图是无向图且无奇数度数点,从1开始执行算法,执行过程如下:
1、从节点1开始执行算法
2、删边1-7, 递归DFS(7)
3、删边7-3, 递归DFS(3)
4、删边3-2,递归DFS(2)
5、删边2-1,递归DFS(1)
6、节点1无边,将1放入栈中,返回
7、节点2无边,将2放入栈中,返回
8、删边3-4,递归DFS(4)
9、 删边4-5,递归DFS(5)
10、 删边5-6,递归DFS(6)
11、删边6-3,递归DFS(3)
12、 节点3无边,将3放入栈中,返回
13、 节点6无边,将6放入栈中,返回
14、节点5无边,将5放入栈中,返回
15、节点4无边,将4放入栈中,返回
16、节点3无边,将3放入栈中,返回
17、节点7无边,将7放入栈中,返回
18、 节点1无边,将1放入栈中,返回
栈中元素自顶至下为: 1,7,3,4,5,6,3,2,1, 恰为一条欧拉回路。

https://www.luogu.com.cn/problem/P2731板子

程序复杂度O(mlogn)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<stack>
 5 using namespace std;
 6 #define N 1500
 7 stack< int >s;
 8 int n,maxn,du[N],ans[N],g[N][N];
 9 void dfs(int u){
10     for(int v=1;v<=maxn;v++)
11         if(g[u][v]){
12             g[u][v]--;
13             g[v][u]--;
14             dfs(v);
15         }
16     s.push(u);
17 }
18 int main(){
19     scanf("%d",&n);
20     for(int i=1,x,y;i<=n;i++){
21         scanf("%d%d",&x,&y);
22         maxn=max(maxn,x);
23         maxn=max(maxn,y);
24         g[x][y]++;
25         g[y][x]++;
26         du[x]++;
27         du[y]++;
28     }
29     int st=1;
30     for(int i=1;i<=maxn;i++)
31         if(du[i]%2){
32             st=i;break;
33         }
34     dfs(st);
35     while(!s.empty()){
36         printf("%d\n",s.top());
37         s.pop();
38     }
39     return 0;
40 }
欧拉回路

 

标签:回路,DFS,栈中,删边,节点,欧拉
来源: https://www.cnblogs.com/liukx/p/12520129.html