[数据结构]第十一章-图论

图的概念

:由V和E两个集合组成的二元组 G(V,E)

子图:V’是V的子集,E’是E的子集,且E’中的边所关联的顶点均在V’中,则G’ = ( V’ , E’ )也是一个图,称其为G的子图

生成子图: V’ = V

连通分支:无向图G的极大连通子图称为G的连通分支。任何连通图都只有一个连通分支,而非连通图有多个连通分支。通俗来讲,一个图被分成几个小块,每个小块是联通的,但小块之间不联通,那么每个小块称为联通分支。一个孤立点也是一个联通分支。

强连通分支:强连通是指一个有向图中任意两点v1、v2间存在v1到v2的路径及v2到v1的路径。强连通的连通分支是强连通分支。

生成树: | E’| = n-1 且G’连通。

极小生成树:包含原图中的所有 n 个结点,并且有保持图连通的最少的边。

图的表示法

1.邻接矩阵表示法

用一个二维数组存储图中各边的信息。

图G的邻接矩阵是一个布尔矩阵,若 i j 间有边则A[i,j]为1。当图是一个网络时A[i , j]为边的权重,无边时为∞。

2.邻接表表示法

对V中的每个顶点,将他的所有邻接顶点存放在一个表中,成为顶点 i 的邻接表。将每个顶点的邻接表存储在G的邻接表数组中。

图的遍历

1、DFS(对应树的前中后序遍历)
2、BFS(对应树的层次遍历)

最短路径

1.单源最短路

Dijkstra算法 O(n^2)

设S为已求出最短路径的结点集合,U为未被选过的结点集合。
开始时dist都为INF,只有源点为0。每次从U中选取一个dist最小的顶点 i 加入S中(该选定的距离就源点v到 i 的最短路径长度)。然后以 i 为新考虑的中间点,修改从 i 点能到达的其他结点的dist值,若从源点到结点 j 的距离(经过 i )比原来距离(不经过 i)短(dist[j] > dist[i]+value[i][j]),则修改dist[j]为 dist[i]+value[i][j],这样直到所有顶点都包含在S中。

这里写图片描述

这里写图片描述

Dijkstra的特点
· 求出n-1条最短路径(单源最短路径)
· 按长度递增的次序
· 只适用于非负权边
· 贪心算法(每次在dist中找最小)

Bellman-Ford算法 O(mn)

第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。
第二,进行循环,循环下标为从1到n-1(n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。
第三,遍历途中所有的边(edge(u,v)),判断是否存在这样情况:
d(v) > d (u) + w(u,v)
则返回false,表示途中存在从源点可达的权为负的回路。

之所以需要第三部分的原因,是因为,如果存在从源点可达的权为负的回路。则 应为无法收敛而导致不能求出最短路径。

Bellman-Ford特点:
· 允许负权边
· 以边为跳板,看是否由于存在某条边而对结果产生影响

SPFA算法(非经典算法,Bellman-Ford的改进)

实现方法为,初始时所有点dist为INF,只有起始点的dist为0。然后建立一个队列,初始时队列里只有起始点,之后不断弹出队首结点 i 去更新它能到达的所有点 j 的dist值,如果dist[j] > dist[i]+value[i][j]则更新成功,再判断下被更新的结点若不在队列中,则把该点加入到队列。这样重复执行直到队列为空。

2.所有顶点间最短路径

Floyd算法(博客很详尽)

算法思想在于逐点试探,看加入这个点是否会影响结果。

for(k=1;k<=n;k++)   
    for(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值