图的题目归类总结

类别

题目

并查集

261, 323, 684

最短路径

743

最小生成树

1135

拓扑排序

207, 210, 802,310

关键路径法

图的知识点补充(AOE网络的关键路径)

图的遍历

133, 332(欧拉路径),  785, 841, 997, 1042, 1306

其它

959, 1043, 1161, 1267, 444

就不贴题目超链接了,可以去请看这里!!!leetcode题目目录!!根据题号找对应题目。

归纳总结:

一、图的遍历(traversing of graph)

1、主要就是dfs(depth-first search)、bfs(breadth-first search)。

2、样例代码,请参考:841. 钥匙和房间

二、并查集(Union-Find)

1、找老大,老大是自己的顶点是该联通域的掌门人。

2、集合的合并,如果一条边的两个顶点老大一样,说明这两个顶点原本就在一个联通域内,该联通域内有环;如果一条边的两个顶点老大不一样,那么就要把他们并到一个集合内。

3、最后,老大的数目决定连通域的个数。

4、样例代码,请参考:684. 冗余连接(并查集)

三、拓扑排序(topological sort)

1、采用邻接表来表示有向图,抽象成:

(1)一个二维数组,里面每一个一维数组存以该索引为顶点的后继顶点。

(2)一个一维数组 in, 来表示每个顶点的入度数目。

2、我们开始先根据输入来建立这个有向图,并将入度数组也初始化好。

3、设置一个stack:

(1)将所有入度为0的点压栈。

(2)从栈中退出栈顶元素输出,并把该顶点引出的所有有向边删去,也就是把它的各个邻接顶点的入度数-1。

(3)将新的入度数为零的顶点再入堆栈。

(4)重复过程(2)-(3),直到栈为空。

4、最后,如果已经输出全部顶点,所有顶点入度数都为0,说明有向图中不存在环;如果没有输出全部顶点,那么剩下的顶点中存在入度不为零的顶点,说明有向图中存在环。

5、样例代码,请参考:207. 课程表(拓扑排序)
 

四、最小生成树(minimum spanning tree , MST)

方法1: Kruskal算法

1、先了解一下Kruskal算法的步骤:

(1)设一个有n个顶点的连通网络为G(V,E),将所有的边按照权值从小到大排序。

(2)当在G中选择一条具有最小权值的边时,若该边的两个顶点落在不同的连通分量上,则将此边加入到T中;否则,即这条边的两个顶点落在同一个连通分量上,会形成环,则将此边舍去,重新选择下一条权值最小的边;如何判断两个顶点是否落在同一个联通分量上,采用并查集来解决。

(3)如此重复下去,直到所有顶点在同一个连通分量上为止。T就是最小生成树。如果最后T中,不能包含所有顶点,那么就没有办法构成最小生成树。

2、Kruskal算法=一个排序+并查集

3、样例代码,请参考:1135. 最低成本联通所有城市(最小生成树)

方法2: prim算法

1、先了解一下Prim算法的步骤:

(1)设一个有n个顶点的连通网络为G(V,E), T(U, TE)是最小生成树。V中存G的顶点,E中存G的边。U中存T的顶点,TE中存T的边。开始时,V中是全部顶点。U和TE都是空的。

(2)第一次先从V中随便取一个顶点加入到U中。

(3)然后从那些其一个端点已经在U中,另一个端点在U外的所有边中找一条最短的边。并把该边和顶点分别并入TE和U中。如此进行下去,每次往生成树里并入一个顶点和一条边,直到n-1次之后,把所有n个顶点都并入U中,此时U=V,T是最小生成树。如果最后T中,不能包含所有顶点,那么就没有办法构成最小生成树。

2、样例代码,请参考:1135. 最低成本联通所有城市(最小生成树)

五、最短路径(shortest path

Dijkstra算法(单源最短路径算法):

1、先了解一下Dijkstra算法的步骤:

(1)设一个有n个顶点的连通网络为G,  顶点集合U和T。最开始的时候,U中存G的全部顶点以及源点到这些顶点的路径长度:源点到自身的路径长度是0,源点到不相连的顶点,长度是无穷大。T为空。

(2)每次去U中找出路径最小的顶点uu,在U中删掉uu,并且将uu插入到S中。

(3)在U中遍历从uu出发能到达的所有顶点v,根据U(v)=min(U(v), S(uu)+W[uu,v]),其中W[uu,v])表示uu到v的路径长度,更新一波U(v)的长度。

(4)重复过程(2)-(3),所有顶点都加入了S中。

2、样例代码,请参考:743. 网络延迟时间(最短路径)

Prim算法和Dijkstra算法的对比:

1、相同点:都是基于贪心的思想,都是一开始两个顶点集合A和B,A为空,B为全部顶点,都是从B中选一个加入到A中,直到全部顶点加入完成。

2、不同点

(1)Prim算法:每次从那些其一个端点已经在A中,另一个端点在B中的所有边中找一条最短的边,加入A中。

(2)Dijkstra算法:每次去B中找出路径最小的顶点uu,加入A中。

还多一个步骤:要根据uu更新一波B中的最短路径长度。在B中遍历从uu出发能到达的所有顶点v,根据B(v)=min(A(v), A(uu)+W[uu,v]),其中W[uu,v])表示uu到v的路径长度,更新一波B(v)的长度。

六、关键路径法(Critical Path Method, CPM)

1、先了解一下CPM的步骤,核心就是5个for 循环

Ev[i]表示事件i的最早出现时间,E[i]表示活动i的最早出现时间,Lv[i]表示事件i的最迟出现时间,L[i]表示活动i的最迟出现时间。

以j顶点指向k顶点为例:

(1)从源点开始向汇点递推,根据Ev[k]=max(Ev[j]+w[j,k]),求出Ev数组其中的最大值Ev[n]是汇点的最早开始时间。

(2)因为汇点就是结束点,其最迟出现时间与最早出现时间相同,即Ev[n]=Lv[n]。将(1)中排好序的事件,从汇点开始向源点递推,根据Lv[j]=min(Lv[k]-w[j,k]),求出Lv数组

(3)活动的最早开始时间与事件的最早开始时间是一样的,求出E数组,E=Ev.

(4)j顶点指向k顶点,中间经历活动aj, 根据L[j]=Lv[k]-(活动j所需的时间),求出L数组

(5)E[i]=L[i]的活动,就是关键活动,由这些活动组成的路径就是关键路径。

(6)有可能关键路径不止一条,那么这时候可以将re按照字典序排序,如果后一条路径的起始点,与前一条路径的结束点不一致,即x[i][0]!=x[i-1][1],删后面一条路径。那么此时多一个for循环

2、样例代码,请参考:图的知识点补充(AOE网络的关键路径)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值