中国邮路问题邮递员问题欧拉路径图论C++

中国邮路问题邮递员问题欧拉路径图论C++_第1张图片
通路:在无向图中由点边交替组成的序列就是通路(如果这个图是简单的,那么也可以使用点的序列来表示),如果首尾的点相同,则称为一条回路
无向图的连通性:无向图中任意一对点之间均有通路
欧拉通路:从某个顶点出发,将所有的边遍历一遍并且仅经过一遍的通路序列称为欧拉通路,连通的多重图有欧拉回路而无欧拉回路当且仅当它恰有两个奇数度顶点
这里说明了欧拉通路的条件:

图是连通的,没有孤立节点
对于无向图来说,奇数度的顶点为2个,这两个顶点分别是起点以及终点(0个的话就是回路了)
欧拉回路:如果欧拉通路的起点与终点一样,则成为欧拉回路, 连通的多重图具有欧拉回路当且仅当它的每个顶点都有偶数度
则欧拉回路的条件:

图是连通的,没有孤立节点
无向图的每个节点的度数都是偶数度,有向图每个节点的入度等于出度
判断图是否存在欧拉回路
根据判断的条件,首先是判断图的连通性,然后判断图的每个节点的度数是否是偶数就可以了:

开始还要判断是否是欧拉回路。因为这个程序主要是针对欧拉回路的。
因为图中奇度顶点组合成4条边的情形有很多种,所以要分别求出每种组合形成的边的代价,然后从中选出代价最小的边。
另外,在此问题中,边的“添加”的应该理解为从一个奇度点到另一个奇度点之间的路径。
“邮递员”问题的算法描述如下:
(1) 建立街区无向网的邻接矩阵;
(2) 求各顶点的度数;
(3) 求出所有奇度点;
(4) 求出每一个奇度点到其它奇度点的最短路径;
(5) 找出距离最短的添加方案;
(6) 根据最佳方案添加边,对图进行修改,使之满足一笔画的条件;
(7) 对图进行一笔画,并输出;

程序首先输入点与边,和点与边的关系,读取结点个数和边条数以及点与点间的连通关系,并建立街区无向网的邻接矩阵,同时记录各结点度数。
随后遍历各结点,找出其中所有的奇点。如果奇点个数大于2,则需要加边来使奇点数为0;如果奇点正好为两个,则从其中一个点出发,到另一点结束能形成欧拉图,但是不能形成回路,也不能保证从邮局出发;如果奇点数为0,则可以形成欧拉回路。接下来分情况讨论:
当奇点数大于2的时候:通过Floyd算法求任意两点路径的最短距离,并将读入的图的数据更新为最短路径。随后进入extend_edge()函数。通过标记的方法来加边。当某一边的始点与终点均为奇点,并且两点间可连通时,将需要加边的始点和终点以及距离信息存入odd_edge中。随后通过一个深度遍历,判断需要加的边是否为最短的,即确定距离最短的添加方案。随后用dijkstra算法确定从该始点到终点的最短路径。
当奇点数等于2的时候,判断起始点能否为1,若可以,则设置first_id = 1即可。若不能,则无法构成环路。
中国邮路问题邮递员问题欧拉路径图论C++_第2张图片

中国邮路问题邮递员问题欧拉路径图论C++_第3张图片
中国邮路问题邮递员问题欧拉路径图论C++_第4张图片

你可能感兴趣的:(C/C++,算法,图论)