ICode9

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

6.4.4 欧拉回路

2022-01-24 23:33:17  阅读:184  来源: 互联网

标签:有向图 奇点 vis 6.4 道路 回路 欧拉


有一条名为Pregel的河流经过Konigsberg城,城中有7座桥,把河中的两个岛与河岸连接起来,当地居民热衷于一个难题,是否存在一条路线,可以不重复地走遍7座桥
首先是抽象为平常中我们常见的一笔画问题,这样的路线称为欧拉道路(eulerian path)

点击查看欧拉回路
C..................
.  .              .
.  .              .
A.................D
.  .              .
.  .              .
B..................

不难发现,在欧拉道路中,“进”和“出”是对应的--除了起点和终点外,其它点的“进出”次数应该相等,换句话说,除了起点和终点外,其他点的度数(degree)应该是偶数
很可惜在七桥问题中,所有四个点的度数均是奇数(这样的点也称为奇点),因此不可能存在欧拉道路,上述条件也是一个充分条件--如果一个无向图是联通的,且最多只有两个奇点,则一定存在欧拉道路。如果有两个奇点,则必须从其中一个奇点出发,另一个奇点终止;如果奇点不存在,则可以从任意点出发,最终一定会回到该点(即起点和终点重合,这个可以通过反证法来证明的),此时这样特殊的道路叫做欧拉回路
用类似推理方式可以得到有向图的结论:最多只能有两个点的入度不等于出度,而且必须是其中一个点的出度恰好比入度大1(把它作为起点),另一个的入度比出度大1(把它作为终点)
当然还有一个前提条件,在忽略边的方向后,图必须是联通的,否则与欧拉道路的题设不服(无向图老问题了,此时退化成有向图)

下面是程序,它同时适用于欧拉道路和欧拉回路(终点和起点是同一点,或者说不存在奇点),但是如果需要打印的是欧拉道路,在主程序中调用的时候,参数必须是道路的起点,另外,打印的顺序是逆序的,因此在真正使用这份代码时,应当把printf语句替换成一条push语句,把边(u,v)压入一个栈内

点击查看代码
void euler(int u) {
  for(int v = 0; v < n; v++) if(G[u][v] && !vis[u][v]) {
  	vis[u][v] = vis[v][u] = 1;//这边应该是标记该边是否已经走过 
  	euler(v);//进行递归 
  	printf("%d %d\n", u, v);
  }
}

尽管上面的代码只使用于无向图,但不难改成有向图,把vis[u][v]=vis[v][u]=1改成vis[u][v]=1就可以了,从无向退化成有向了
根据连通性和度数可以判断出无向图和有向图是否存在欧拉道路和欧拉回路
可以用DFS构造欧拉回路(这边的思路参考上节中的拓扑排序中的dfs,两者的构造有非常类似的地方,只不过欧拉回路允许存在有向环罢了)
注意做图的题目的时候时常需要有抽象思维进行图像化

Play_On_Words题解
切记open的过去式没有双写,不要习惯性多打字母opened

标签:有向图,奇点,vis,6.4,道路,回路,欧拉
来源: https://www.cnblogs.com/FlnButFly/p/15841362.html

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

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

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

ICode9版权所有