ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

欧拉回路

2020-03-18 21:01:11  阅读:393  来源: 互联网

标签:回路 DFS 栈中 删边 节点 欧拉


七桥问题

定义 如果图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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有