§7.4 图的连通性问题 §7.4.1 无向图的连通分量和生成树 1.求连通分量 每外部调用一次DFS或BFS,可求一连通分量的顶点集

Slides:



Advertisements
Similar presentations
复习: :对任意的x∈A,都有x∈B。 集合A与集合B间的关系 A(B) A B :存在x0∈A,但x0∈B。 A B A B.
Advertisements

第五章 二次型. 第五章 二次型 知识点1---二次型及其矩阵表示 二次型的基本概念 1. 线性变换与合同矩阵 2.
第四章 二元关系 4.1 二元关系及其表示法 序偶与笛卡尔积
第七章 图 7.1 图的定义和术语 7.2 图的存储结构 7.3 图的遍历 7.4 图的连通性问题 7.5 有向无环图及其应用
复习:树 树的基本概念和术语 二叉树的概念及性质 二叉树的存储结构 遍历二叉树 线索二叉树 树的应用:哈夫曼树 顺序存储 链式存储 递归算法
常用逻辑用语复习课 李娟.
第三节 格林公式及其应用(2) 一、曲线积分与路径无关的定义 二、曲线积分与路径无关的条件 三、二元函数的全微分的求积 四、小结.
树的基本概念 离散数学─树 南京大学计算机科学与技术系.
数据结构 第7章 图.
第六章 图(一).
第七章 图 (Graph)
Ch.7 图 图是一种复杂的非线性结构 应用:AI、工程、数学、生物、计算机 结点间的逻辑关系:任两个结点都可能相关
第9章 图 图的基本概念 图的存储结构 图的实现 图的遍历 最小生成树 最短路径 拓扑排序 关键路径 主要知识点.
第七章 图 7.1 图的基本概念 7.2 图的存储表示 7.3 图的遍历 7.4 图的生成树 7.5 最短路径 7.6 拓扑排序
图(一).
第七章 图 1、图的基本概念 2、图的存储表示 3、图的遍历与连通性 4、最小代价生成树 5、最短路径问题 6、AOV网络和AOE网络.
图的遍历.
Chapter 6 Graphs.
强连通分量 无向图 1、任意两顶点连通称该图为连通图 2、否则将其中的极大连通子图称为连通分量 A D C B E 有向图
第七章 图.
7.1 抽象数据类型图的定义 7.2 图的存储表示 7.3 图的遍历 7.4 最小生成树 7.5 重(双)连通图和关节点
第七章 图.
知识点回顾 生成树、生成森林 概念、生成过程 最小生成树 概念、 MST 性质 普里姆算法和克鲁斯卡尔算法.
第七章 图 知识点2:图的存储结构.
第七章 图 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
第7章 图 本章主题:图的基本概念、图的存储结构和图的常用算法 教学目的: 教学重点:图的各种存储方式及其运算
第七章 图.
§7.4.2 最小生成树( Minimum Spanning Tree)
第7章 图 7.1 图的定义和术语 7.2 图的存储结构 7.3 图的遍历 7.4 图的连通性问题 7.5 有向无环图的应用
第七章 图.
使用矩阵表示 最小生成树算法.
无向树和根树.
第 五 章 图 论 (第二部分) 1. 通路 2. 图的连通性.
第6章 图 本章中介绍下列主要内容: 图的定义 图的存储结构 图的遍历操作 图的几个典型问题.
四、投影运算 在数据库中, 用关系来描述数据时常用投影运算进行数据操作。
知识点回顾 拓扑排序 关键路径 应用领域、求解步骤、算法实现过程 应用领域 求解步骤
第八章 图 图的基本概念 图的存储表示 图的遍历与连通性 最小生成树 最短路径 活动网络.
Graphs.
8.1 图的基本概念 8.2 图的存储结构 8.3 图的遍历 8.4 生成树 8.5 最短路径 8.6 拓扑排序 8.7 关键路径
复习 图的定义和术语 图(Graph)、有向图、无向图、子图、有向完全图 、完全图、稀疏图、稠密图、权、网、邻接点、相关边、度、路径、路径长度、回路、简单路径、简单回路、连通、连通图、连通分量、强连通图、强连通分量、生成树 图的存储方法 给定一个图,画出邻接矩阵、邻接表 图的邻接矩阵和邻接表的存储算法.
顺序表的删除.
定理 6.10(五色定理):任何平面图G是5-可着色的。
复习.
生成树.
Open Topic 1-9(1) : 概念辨析 2017 年 12 月 11 日 何润雨 & 孙思钰 中文翻译仅供参考
第16讲 相似矩阵与方阵的对角化 主要内容: 1.相似矩阵 2. 方阵的对角化.
§6.7 子空间的直和 一、直和的定义 二、直和的判定 三、多个子空间的直和.
图(二).
知识点回顾 图的深度优先和广度优先遍历思想 图的深度优先遍历算法(用邻接表作为存储结构) 图的广度优先遍历算法(用邻接矩阵作为存储结构)
第6讲 等价关系、相容关系 与偏序关系 主要内容: 1.等价关系. 2.相容关系. 3.偏序关系..
1.2 子集、补集、全集习题课.
1.设A和B是集合,证明:A=B当且仅当A∩B=A∪B
树和图 tree and graph 蔡亚星.
学习任务三 偏导数 结合一元函数的导数学习二元函数的偏导数是非常有用的. 要求了解二元函数的偏导数的定义, 掌握二元函数偏导数的计算.
第七、八次实验要求.
第六章 图 本章的主要内容是: 图的逻辑结构 图的存储结构及实现 图的连通性 最小生成树 最短路径 AOV网与拓扑排序 AOE网与关键路径.
第15讲 特征值与特征向量的性质 主要内容:特征值与特征向量的性质.
§2 方阵的特征值与特征向量.
最小生成树.
第七章 图 £7.1 图的定义和术语 £7.2 图的存储结构 £7.3 图的遍历 £7.4 图的连通性问题 £7.5 有向无环图及其应用
4.2 图的存储结构(cont.) v1 v2 v3 v4 v5 vertex= v1 v2 v3 v4 v5 v
第六章 图.
数据结构 第六章 图.
树的基本概念.
第三部分 图论 本部分主要内容 图的基本概念 树 欧拉图与哈密顿图 二部图与匹配 平面图 着色.
第7章 图.
计算机问题求解 – 论题1-9 - 关系及其性质 2018年11月13日.
1、图的基本概念 2、图的存储结构 3、图的遍历与连通性
最小生成树 最优二叉树.
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
Presentation transcript:

§7.4 图的连通性问题 §7.4.1 无向图的连通分量和生成树 1.求连通分量 每外部调用一次DFS或BFS,可求一连通分量的顶点集 2.生成树和生成森林 生成树 连通图G和极小连通子图,但包含G的所有顶点(支撑树),不唯一 n个顶点的连通图的生成树一定有n-1条边

§7.4.1 无向图的连通分量和生成树 生成森林:各连通分量的生成树集合 求生成树和生成森林(使用DFS和BFS) 设G是无向图,∀v∈V(G)做出发点 若图连通,则做一次DFS或BFS,必将G中n个顶点都访问到,且只做一次访问 两种搜索方法中,从vi搜索到vj时,须经过边(vi,vj),故只需添加输出边的操作即可:

§7.4.1 无向图的连通分量和生成树 在dfs和bfs中,均在 while(p) { if( !Visited[p->adjvex] ) { 加入打印:(i,p->adjvex) //dfs须在递归前加入 } 若G连通则求出的为生成树,否则为生成森林 若G为有向图,仅当源点为有根图的根时,才能求得生成树,否则为生成森林

§7.4.1 无向图的连通分量和生成树 Ex. 7.5, 7.22, 7.23

§7.4.2 最小生成树( Minimum Spanning Tree) 设G是连通图,G的生成树不唯一 MST:权最小的生成树,树的权是各边上的权值之和 应用 n个城市之间的通信网,可构建n(n-1)/2条线路 n个城市连通至少要n-1条线路,G的生成树是1个可行的方案 最小生成树是最经济的可行方案

MST性质-大多数算法都利用了此性质 设G=(V,E)是一连通图,U是V的真子集,若(u,v)是所有连接U和V-U的边中权最小的边(轻边),则一定存在G的一棵最小生成树包括此边。 Pf:设G的任何一棵最小生成树均不包括(u,v); T’ u v v’ u’ T U V-U

∴必有一路径P连接u和v,且P上必有一紫边连接红点集和白点集,不妨设其为(u’,v’) 将轻边加入T上,和P形成回路; V-U T是G的1棵MST,轻边(u,v)∉T ∵T连通且包含所有顶点 ∴必有一路径P连接u和v,且P上必有一紫边连接红点集和白点集,不妨设其为(u’,v’) 将轻边加入T上,和P形成回路; 删(u’,v’)消除圈后形成树T’ ∵w(u,v)≤w(u’,v’) ∴w(T’)=w(T)+w(u,v)-w(u’,v’) ≤w(T) T’亦是G的MST,他包含轻边

就是找轻边扩充到当前生成的树T=(U,TE)中 构造MST 就是找轻边扩充到当前生成的树T=(U,TE)中 U-红点集、红边(连接2红点)集,构成T V-U-白点集、白边(连接2白点)集 紫边集-连接红点和白点的边 轻边-权最轻的紫边,或最短紫边(若权为长度):(u1,v1) u1 v1 U V-U 5 50 15 23 u2 u3 v2 v3

1、Prim算法 特点 基本思想(贪心法) 设V(G)={0,1,…,n-1} 当前形成的集合T=(U,TE)始终是一棵树 T中的顶点和边均为红色 基本思想(贪心法) 设V(G)={0,1,…,n-1} 算法的每一步均是在连接红、白点集的紫边中选一轻边扩充到T(贪心),T从任意一点r开始(r为根),直至U=V为止。MST性质保证了贪心选择策略的正确性。

1、Prim算法 如何找轻边? 可能的紫边集 设红点集|U|=k, 白点集|V-U|=n-k,则可能的紫边数为:k(n-k)。 在此紫边集中选择轻边效率太低。 构造候选轻边集 构造较小的紫边集,但保证轻边在其中。 因为,∀v∈白点集,从v到各红点的紫边中,只有最短的那一条才可能是轻边,所以只须保留所有n-k个白点所关联的最短紫边作为轻边候选集即可。 显然,轻边是该候选集中权最轻的边。 可以针对红点集来构造候选轻边集吗?

1、Prim算法 如何维护候选轻边集? 当把轻边(u,v)扩充至T中时, v由白点变为红点,紫边(u,v)变为红边(u,v); ∵对每个剩余白点j,边(v,j)由白变紫,此新紫边的长度可能小于白点j原来所关联的最短紫边。 ∴须调整候选轻边集,用更短的新紫边(v,j)取代原来关联于j的最短紫边。

1、Prim算法 算法梗概 PrimMST(G,T,r) { //求以r为根的MST InitCandidateSet(…); for (k=0; k<n-1; k++) { //求T的n-1条树边 (u,v)=SelectLightEdge(…); //选轻边,可能不唯一 TE=TE∪{(u,v)}; //将(u,v)涂红加入树中,白点v加入红点集 ModifyCandidateSet(…); //根据新红点v调整候选轻边集 } 算法终止时U=V,T=(V,TE)

1、Prim算法 实例 2 3 5 4 1 6 7 2 3 5 4 1 6 ∞ 2 3 5 4 1 1 1 1 1 3 1 3 1 3 5 5 5 2 2 2 3 2 2 2 5 5 4 4 4 4 5 4 5 4 5

1、Prim算法 存储结构 #define Infinity INT_MAX //表示最大整数 #define n 100 typedef int AdjMatrix[n][n]; //邻接矩阵 typedef struct { //树边 int fromvex, tovex; //起点、终点 int len; //边长度,权值 } MST[n-1]; 设邻接矩阵初值:不存在的边其权值为Infinity

1、Prim算法 算法求精-初始化 } } ; 将根r涂红加入红点集U,TE=φ。 对每个白点i (0≤i ≤n-1, i≠r ), i所关联的最短紫边(r,i)的长度为G[r][i], 这n-1条最短紫边构成了初始的候选轻边集。 因为树边为空,故将T[0..n-2]全部用来存放候选轻边集。 void InitCandidateSet (AdjMatrix G, MST T, int r) { int i, k=0; for (i=0; i<n; i++) //依次形成白点i初始的最短紫边存放在T[k]中 if ( i != r ) { T[k].fromvex=r; //紫边起点为红点 T[k].tovex=i; //紫边终点为白点 T[k++].len=G[r][i]; //紫边长度,权值 } } ;

1、Prim算法 算法求精-选轻边 int SelectLightSet ( MST T, int k) { 在当前候选轻边集T[k..n-2]中,选长度最短的紫边。(Note:T[0..k-1]是红边集,T也是树,为什么针对白点构造候选集更好?) int SelectLightSet ( MST T, int k) { int i, minpos, min=Infinity; for (i=k; i<n-1; i++) //遍历候选集找轻边 if ( T[i].len < min ) { min=T[i].len; //紫边起点为红点 minpos=i; //记录当前最短紫边的位置 } if (min==Infinity ) error( “G不连通”); return minpos; //轻边为T[minpos] } ;

1、Prim算法 算法求精-调整候选轻边集 for (i=k; i<n-1; i++) { //遍历候选集 设轻边(u,v)涂红后加入到树边中,T[k..n-2]是待调整的候选轻边集,则须根据新红点v调整T[k..n-2] 。 void ModifyCandidateSet ( AdjMatrix G, MST T, int k, int v) { int i, d; //v是新红点 for (i=k; i<n-1; i++) { //遍历候选集 d=G[v][T[i].tovex]; //T[i]的终点是白点,d是新紫边的长度 if ( d<T[i].len ) {//d小于白点T[i].tovex原关联最短紫边长度 T[i].len=d; T[i].fromvex=v; //新紫边取代T[i].tovex原来的最短紫边 } } ;

1、Prim算法 算法求精-最终算法 void PrimMST(AdjMatrix G, MST T, int r) { int k,m,v; InitCandidateSet(G, T, r);//初始候选集T[0..n-2] for (k=0; k<n-1; k++) { //求n-1条树边中的kth条 m=SelectLightEdge(T,k); // 在T[k..n-2]选轻边T[m] T[m]↔T[k];//轻边和紫边T[k]交换,将其扩充至树中 v=T[k].tovex; //交换后红边集为T[0..k],v是新红点 ModifyCandidateSet(G,T,k+1,v); //T[k+1..n-2]是新候选集,根据新红点v调整候选轻边集 }

1、Prim算法 时间分析 初始化:O(n) 在k循环中: Select中循环次数为n-k-1 // 在T[k..n-2]选轻边T[m] Modify中循环次数为n-k-2 //T[k+1..n-2]是新候选集,根据新红点v调整候选轻边集 因此: 时间为O(n2),与边无关,适合稠密图。

2、Kruskal算法 特点:当前形成的集合T除最终结果外,始终是森林,无环。 算法: KruskalMST(G){ T=(V, φ);//包含n个顶点,不含边的森林; 依权的增序对E(G)中边排序,设结果在E[0..e-1]; for (i=0; i<e; i++) { 取E中第i条边(u,v); if (u和v分属森林T中两棵不同的树) then T=T∪{(u,v)}; //否则产生回路,放弃此边 if (T已是一棵树)then return T; }//endfor }

2、Kruskal算法(续) 例子:略 时间: 结论:时间性能主要取决于边数,适合稀疏图。 Ex.7.7 对边排序O(elge) for循环中: 检测每条边的两个顶点是否在同一连通分量(树)上 只要采用合适的数据结构,检测时间为O(lge) 因此,此时间亦为O(elge)。 总计: O(elge) 结论:时间性能主要取决于边数,适合稀疏图。 Ex.7.7

§7.5 拓扑排序 有向无环图DAG(Directed Acyclic Graph)的应用

1、相关概念 集合与关系 笛卡儿积:设A、B是两个集合,所有序偶(x,y)构成的集合(x∈A, y ∈B ),称为A,B的笛卡儿积,记为A×B。 二元关系:集合A×B的一个子集R,称为集合A与B上的一个二元关系,简称关系。若B=A,则R称为A上的一个二元关系,他刻画了集合A中两个元素之间的关系。若(x,y)∈R,则称x和y有关系R,亦可记为xRy,否则x和y没有关系R,记为x y。 集合A上的关系R是自反的(反身的),若对∀x ∈A,都有xRx。 集合A上的关系R是对称的,若xRy,则yRx。其中,x,y ∈A。 集合A上的关系R是反对称的,若xRy,yRx,则必有x=y.其中x,y ∈A。 集合A上的关系R是传递的,若xRy,yRz,则xRz。其中x,y,z ∈A。 例子: 数之间的相等关系,具有自反性,对称性,传递性,反对称性; 数之间的小于关系,具有传递性,反对称性; 数之间的小于等于关系,具有自反性,传递性,反对称性; R

1、相关概念 偏序(部分序) 设R是集合A上的一个关系,若R具有自反性,反对称性和传递性,则称R是A上的偏序关系,A是偏序集(对于R)。 偏序关系R一般记为≤,若将关系看作是比较,则偏序关系是指集合中仅有部分元素是可以比较的。 全序(线性序) 设R是集合A上的一个偏序关系,若对 ∀x,y ∈A,必有xRy或yRx, 则称R是A上的全序关系,A是全序集(对于R)。 数集合上的大小关系是全序关系 全序关系是指集合中全体成员之间均可比较。

1、相关概念 拓扑排序 将一个dag图G=(V,E)中的所有顶点排成一个线性序列,使得对G中任意一对顶点u和v,若<u,v> ∈E,则在线性序列中u在v之前。这种给顶点定序的操作称为拓扑排序。 拓扑(有序)序列:上述顶点的线性序列称为拓扑序列。唯一吗? 几何意义:将G中顶点按拓扑序列的次序排成一行,则G中所有的有向边的指向均为从在到右 例子: v2 v1 v2 v3 v4 v3 v1 v4

1、相关概念 拓扑排序 拓扑排序成功的充要条件:无环。 例子: 应用背景 有向图G可表示事件之间的先后关系,顶点表示事件,边表示事件之间的依赖关系: <u,v>∈E(G) 表示u先于v发生,u完成后才能开始v。 若G表示施工图、生产流程图、学习计划安排,则在只能串行工作时,拓扑序列是一种可行的方案或计划。 v4 v3 v2 v1

2、求拓扑序列? (1) 无前驱的顶点优先 算法思想:输出当前入度为0的顶点。 NonPreFirstTopSort(G){ while( G中有入度为0的顶点 ) do { 从G中选1个入度为0的顶点v输出之; 从G中删v及其出边,出边终点的入度减1; } if ( 输出的顶点数 < | V(G) | ) then Error ( “G有环,排序失败” );

2、求拓扑序列? (1) 无前驱的顶点优先  例子:输出v1, v4, v3, v2, v5 Step1: 删v1或v4 Step:

2、求拓扑序列? 算法实现 void NonPreFirstTopSort(ALGraph G){ //以下vi简称为i 增加一局部向量indegree[0..n]保存各顶点的当前入度 或者在邻接表的顶点表中增加入度域 用栈(或队列)来保存所有入度为0的顶点,以免每次选入度为0的顶点 时扫描整个indegree向量 void NonPreFirstTopSort(ALGraph G){ //以下vi简称为i int indegree[MaxVertexNum],i,j,count=0; SeqStack S; EdgeNode *p; for( i=0; i<G.n; i++ ) indegree[i]=0; for( i=0; i<G.n; i++ ) //对每个顶点i for( p=G.adjlist[i].firstedge; p; p=p->p->next)//扫描i的出边表 indegree[p->adjvex]++; //将<i,j>的终点j入度加1,j=p->adjvex InitStack(&S); for (i=0; i<G.n; i++) if ( !indegree[i] ) Push(&S,i);//入度为0的顶点入栈

2、求拓扑序列? while( !StackEmpty(&S) ){//栈非空时,图中仍有入度为0的顶点 i=Pop(&S); //删除无前驱的顶点i printf(“%c\t”,G.adjlist[i].vertex); //输出顶点i count++; //输出顶点计数 for (p=G.adjlist[i].firstedge; p; p==p->next){ //扫描顶点i的出边表 j=p->adjvex; //j是<i,j>的终点 indegree[ j ]--; //j的入度减1,相当于删出边<i,j> if ( ! indegree[ j ] ) Push(&S, j); //j的入度为0则进栈 } if ( count<G.n ) printf( “\nG is not a DAG\n”); 时间:初始化O(n+e) 排序成功时最大:每个顶点入出栈各1次,每个边表节点被检查1次O(n+e)

2、求拓扑序列? (2) 无后继的顶点优先 算法思想:输出当前出度为0的顶点。 NonSuccFirstTopSort(G){ //应选G的逆邻接表 while( G中有出度为0的顶点 ) do { 从G中选1个出度为0的顶点v输出之; 从G中删v及其入边,入边起点的出度减1; } if ( 输出的顶点数 < | V(G) | ) then Error ( “G有环,排序失败” ); 输出结果:逆拓扑序列 算法实现:略

2、求拓扑序列? (3) 利用dfs遍历算法 原理:因为当从某顶点v出发的dfs搜索完成时,v的所有后继必定均已访问过(想象他们均已被删除),此时v相当于是无后继的顶点,所以可在dfs算法返回前输出顶点v,即可得到DAG的逆拓扑序列。 算法: DFSTopSort(G,i,T){ //在DFSTraverse中调用此算法,T是栈 visited[i]=TRUE; //访问i for (所有i的邻接点j)//即< i, j> ∈E(G) if ( !visited[ j ] ) DFSTopSort(G,j,T); Push(&T, i)//从i出发的搜索已完成,输出i } 特点:与NonSuccFirstTopSort算法类似;若G有环,则不能正常工作 Ex.7.9