图-最小生成树

  • 1 普里姆算法
  • 2 克鲁斯卡尔算法
  • 3 重(双)连通图和关节点
  • 4 两点之间的最短路径问题
    • 4.1 源点到其余各点的最短路径
    • 4.2 每一对顶点之间的最短路径
  • 5 拓扑排序
  • 6 关键路径
  • 待处理

问题:如图假设要在 n 个城市之间建立通讯联络网,则连通 n 个城市只需要修建 n-1 条线路,如何在最节省经费的前提下建立这个通讯网?

该问题等价于:构造网的一棵最小生成树,即:在 e 条带权的边中选取 n-1条 (不构成回路),使 “权值之和” 为最小。

最小代价生成树(Minimum Cost Spanning Tree)(简称为最小生成树)。
一棵生成树的代价就是树上各边的代价之和。
构造最小生成树可以有多种算法。其中多数算法利用了最小生成树的下列一种简称为 MSTMSTMST 的性质:假设 N=(V,{E})N=(V,\ \{E\})N=(V, {E}) 是一个连通网,UUU 是顶点集 VVV 的一个非空子集。若 (u,v)(u,\ v)(u, v) 是一条具有最小权值(代价)的边,其中 u∈Uu\in Uu∈U,v∈V−Uv\in V-Uv∈V−U ,则必存在一棵包含边 (u,v)(u,\ v)(u, v) 的最小生成树。

1 普里姆算法

假设 N=(V,{E})N=(V,\ \{E\})N=(V, {E}) 是连通网,TETETE 是 NNN 上最小生成树中边的集合。
算法从 U={u0}(u0∈V)U=\{\ u_{0}\ \}\ \ (u_{0} \in V)U={ u0​ }  (u0​∈V) ,TE={}TE=\{\ \}TE={ } 开始,重复执行下述操作:在所有 u∈Uu\in Uu∈U ,v∈V−Uv \in V-Uv∈V−U 的边 (u,v)∈E(u,\ v )\in E(u, v)∈E 中找一条代价最小的边 (u0,v0)(u_{0},\ v_{0})(u0​, v0​) 并入集合 TETETE,同时 v0v_{0}v0​ 并入 UUU,直至 U=VU=VU=V 为止。此时 TETETE 中必有 n−1n-1n−1 条边,则 T=(V,{TE})T=(V,\ \{TE\})T=(V, {TE}) 为 NNN 的最小生成树。

可取图中任意一个顶点v作为生成树的根,之后若要往生成树上添加顶点w,则在顶点v和顶点w之间必定存在一条边,并且该边的权值在所有连通顶点v和w之间的边中取值最小。
一般情况下,假设n个顶点分成两个集合:U (包含已落在生成树上的顶点)和 V-U (尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边。

假设以二维数组表示网的邻接矩阵,且令两个顶点之间不存在的边的权值为机内允许的最大值(INT_MAX),则普里姆算法如下所示:

//此代码图的存储结构采用的是邻接矩阵
void MiniSpanTree_PRIM(MGraph G, VertexType u){//用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边。//记录从顶点集U到V-U的代价最小的边的辅助数组定义://struct {// VertexType adjvex;//    VRType lowcost;//}closedge[MAX_VERTEX_NUM];k = LocateVex(G, u);for(j=0; j<G.vexnum; ++j){ //辅助数组初始化if(j!=k){closedge[j] = {u, G.arc[k][i].adj}; //{adjvex, lowcost}}}closedge[k].lowcost = 0; //初始 U = {u}for(i=1; i<G.vexnum; ++i){ //选择其余G.vexnum-1个顶点k = minimum(closedge); //求出T的下一个结点;第k顶点//此时 closedge[k].lowcost = MIN{closedge[vi].lowcost | closedge[vi].lowcost>0, vi 属于 V-U )printf(closedge[k].adjvex, G.vexs[k]); //输出生成树的边closedge[k].lowcost = 0; //第k顶点并入U集for(j=0; j<G.vexnum; ++j){if(G.arcs[k][j].adj < closedge[j].lowcost){ //新顶点并入U后重新选择最小边closedge[j] = {G.vexs[k], G.arcs[k][j].adj};}}}
} //MiniSpanTree_PRIM

2 克鲁斯卡尔算法

假设连通网 N=(V,{E})N=(V,\ \{E\})N=(V, {E}) ,则令最小生成树的初始状态为只有 nnn 个顶点而无边的非连通图 T=(V,{})T=(V,\ \{\ \})T=(V, { }) ,图中每个顶点自成一个连通分量。在 EEE 中选择代价最小的边,若该边依附的顶点落在 TTT 中不同的连通分量上,则将此边加入到 TTT 中,否则舍去此边而选择下一条代价最小的边。依次类推,直至 TTT 中所有顶点都在同一连通分量上为止。

为使生成树上边的权值之和最小,显然,其中每一条边的权值应该尽可能地小。克鲁斯卡尔算法的做法就是:先构造一个只含 n 个顶点的子图 SG ,然后从权值最小的边开始,若它的添加不使 SG 中产生回路,则在 SG 上加上这条边,如此重复,直至加上 n-1 条边内止。

算法:
构造非连通图 ST=(V,{});ST=(V,\ \{\ \ \});ST=(V, {  });
        k=i=0;
        while(k<n-1){
                ++i;
                //从边集E中选取第i条权值最小的边(u,v);
                //若(u,v)加入ST后不使ST中产生回路,
                //则输出边(u,v),且k++;
        }

假设连通网 N=(V,{E})N=(V,\ \{E\})N=(V, {E}) ,则令最小生成树的初始状态为只有 n 个顶点而无边的非连通图 T=(V,{})T=(V,\ \{ \})T=(V, {}) ,图中每个顶点自成一个连通分量。在 EEE 中选择代价最小的边,若该边依附的顶点落在T中不同的连通分量上,则将此边加人到 TTT 中,否则舍去此边而选择下一条代价最小的边。依次类推,直至 TTT 中所有顶点都在同一连通分量上为止。

由于普里姆算法的时间复杂度为 O(n2)O(n^2)O(n2),则适于稠密图;
克鲁斯卡尔算法需对 e 条边按权值进行排序,其时间复杂度为 O(elog2e)O(elog_{2}e)O(elog2​e),则适于稀疏图.

3 重(双)连通图和关节点

问题:若从一个连通图中删去任何一个顶点及其相关联的边,它仍为一个连通图的话,则该连通图被称为重(双)连通图

若连通图中的某个顶点和其相关联的边被删去之后,该连通图被分割成两个或两个以上的连通分量,则称此顶点为关节点

没有关节点的连通图为重(双)连通图

关节点的特征:
假设从某个顶点 V0V_{0}V0​ 出发对连通图进行深度优先搜索遍历,则可得到一棵深度优先生成树,树上包含图的所有顶点。

若生成树的根结点,有两个或两个以上的分支,则此顶点(生成树的根)必为关节点;
对生成树上的任意一个“顶点”,若其某棵子树的根或子树中的其它“顶点”没有和其祖先相通的回边,则该“顶点”必为关节点。




4 两点之间的最短路径问题

4.1 源点到其余各点的最短路径




4.2 每一对顶点之间的最短路径

5 拓扑排序

6 关键路径

待处理

——《数据结构图 (C语言版) 严蔚敏》 学习笔记

7.3 图-最小生成树相关推荐

  1. 求的带权图最小生成树的Prim算法和Kruskal算法

    求的带权图最小生成树的Prim算法和Kruskal算法 最小生成树的概念 最小生成树其实是最小权重生成树的简称. 一个连通图可能有多个生成树.当图中的边具有权值时,总会有一个生成树的边的权值之和小于或 ...

  2. ds图—最小生成树_Java: Kruskal算法生成最小生成树(邻接矩阵)

    Java: Kruskal算法生成最小生成树(邻接矩阵): package 输出: Kruskal=36: (E,F) (C,D) (D,E) (B,F) (E,G) (A,B) 分析: Java: ...

  3. ds图—最小生成树_Python实现最小生成树

    Python实现最小生成树--Prim算法和Kruskal算法 文章目录 Python实现最小生成树--Prim算法和Kruskal算法 前言 设计 需求分析 系统设计 系统实现 Prim算法 Kru ...

  4. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

  5. 数据结构(五)图---最小生成树(普里姆算法)

    一:最小生成树 (一)定义 我们把构造连通网的最小代价生成树称为最小生成树或给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. (二)什么是最小生成树? 1. ...

  6. 【恋上数据结构】图代码实现、最小生成树(Prim、Kruskal)、最短路径(Dijkstra、Bellman-Ford、Floyd)

    图 最小生成树(Minimum Spanning Tree) Prim算法 切分定理 Prim算法 – 执行过程 Prim算法 – 代码实现 Kruskal算法 Kruskal算法 – 执行过程 Kr ...

  7. 数据结构(12)----图(遍历、最小生成树、easyX可视化)

    从图的某一顶点出发访问遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traversing Graph). 深度优先遍历(Depth_Frist_Search),也有称为深度优先搜 ...

  8. LeetCode 1489. 找到最小生成树里的关键边和伪关键边(并查集+kruskal最小生成树)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个 n 个点的带权无向连通图,节点编号为 0 到 n-1 ,同时还有一个数组 edges ,其中 edges[i] = [fromi, toi, w ...

  9. 普里姆(Prim)算法 Java实现(最小生成树)

    构造最小生成树的Prim算法(从顶点的思想) 自己的话描述: 1. 从任意一个顶点开始.临时权值数组就是该顶点的权值数组. 2. 找到一条权重最小的边,然后把这两个顶点视为一个顶点,新加入的顶点在临时 ...

最新文章

  1. js实现的时间轴效果
  2. 数据与分析领域的十大技术趋势
  3. 解决Springboot+JPA中多表关联查询会查询多次的问题(n+1查询问题)
  4. 数据解析1:XML解析(2)
  5. [caffe]深度学习之图像分类模型AlexNet解读
  6. Shiro+springboot+mybatis(md5+salt+散列)认证与授权-02
  7. VTK:Utilities之OffScreenRendering
  8. RadioWar_RFID_LiveCD_Alpha330
  9. Redis总结(四)Redis 的持久化
  10. | 一文读懂迁移学习(附学习工具包)
  11. 2017 软工作业结队第二次作业
  12. 私人影院音响效果如何有效提升?
  13. 下划线(Underline)与低线(Lowline)的差异
  14. 竞争情报(CI,competitive intelligence)都需要哪些因素
  15. 论文阅读Targetless Calibration of LiDAR-IMU System Based on Continuous-time Batch Optimization(含代码解读)
  16. 我们正处在大数据时代,浅谈大数据
  17. 带有详细书签的IT电子书大全
  18. face_detect
  19. 信息安全实验室在银行网络中的应用
  20. 数据质量分析之信息调研

热门文章

  1. ubuntu22.04安装ros教程
  2. 推荐几个c++自学网站
  3. 成人高等教育计算机,成人高等教育计算机实验教学研究
  4. 访问我的路径C:\Users\14575\Documents\Tencent Files\1457518657\FileRecv\face\face
  5. 【海康威视】前端开发:【2】Web无插件版Demo测试
  6. AD画PCB飞线显示不全,DRC检查不出来
  7. 【ROS】虚拟机VMware 安装ROS 一条龙教程+部分报错解决
  8. 3. Git 下载安装
  9. 小程序如何做成html的滚动字幕,小程序两种滚动公告栏的实现方法
  10. STM32读写内部Flash(介绍+附代码)