基础图论算法

首先还是感谢 Alex_Wei 的博客 图论基础
这篇博客可以理解成学习笔记之类的.所以记叙比较散乱是正常的.嗯.

一.最短路

以下内容,提最短路时若不做特殊说明,默认图是 无负环的存在负权有向图

结论

  1. 最短路中不存在环.

若存在环,只能是负环.

  1. 单源最短路中,源点到图中任意一点的最短路最多有 n − 1 n-1 n1 条边.

考虑 n − 1 n-1 n1 条边构成图中可能存在的最小的链.若存在超过 n − 1 n-1 n1 条边,则路径上有环.这与 结论 1 矛盾.

  1. 最短路树
    对于每个点的最短路,考虑将它最短路上的前驱节点(若有若干,选择其中一个) v ( d i s u = d i s v + w ) v(dis_u=dis_v+w) v(disu=disv+w) 认作其父亲.则若所有点对源点都可达,这样会形成一种树形结构满足源点出发的任意一条路径都是最短路.我们叫他最短路树.
    最短路树不止一种.若保留所有的

算法

SPFA

SPFA 是 Bellman-Fold 算法的队列优化.
其核心思想是对全点做 n − 1 n-1 n1 轮松弛.即遍历边 e ( u → v , w ) e(u \rightarrow v, w) e(uv,w),检查若 d i s v > d i s u + w dis_v>dis_u+w disv>disu+w,令 d i s v ← d i s u + w dis_v \leftarrow dis_u+w disvdisu+w
松弛 i i i 轮后, d i s u dis_u disu 表示源点到 u u u 经过边数不超过 i i i 的最短路长度.

SPFA 判断负环

初始时,将全点丢入队列, d i s dis dis 赋为 0 0 0.执行 SPFA 并更新每个点的 入队次数,若发现某点入队次数 ≥ \ge n − 1 n-1 n1,则原图存在负环.

入队次数,其实等于最短路经过的边数.当第 x x x 次入队时,一定有路径边数 ≥ x \ge x x.否则它肯定会在之前的轮次更新.

差分约束系统

考虑一组变元 ( x 1 , x 2 , x 3 , . . . , x n ) (x_1, x_2, x_3, ..., x_n) (x1,x2,x3,...,xn) 的取值:
若存在若干组限制 x i + d ≥ x j x_i+d \ge x_j xi+dxj.如何构造满足所有限制的解.

发现 x i + d ≥ x j x_i+d \ge x_j xi+dxj 形如最短路里的三角形不等式:
对于任意一种单元最短路,若存在边 e ( u → v , w ) e(u \rightarrow v, w) e(uv,w),一定有 d i s u + w ≥ d i s v dis_u+w \ge dis_v disu+wdisv

于是我们对于每组限制,建边 e ( x i → x j , d ) e(x_i \rightarrow x_j, d) e(xixj,d),然后进行最短路算法即可.

为了防止存在单元最短路无法扩展到的点,通常,我们会建立超级源点 S S S,并对所有点建边 e ( S → u , 0 ) e(S \rightarrow u, 0) e(Su,0)
这显然不会影响答案的正确性.只是限制了求解出的 x i x_i xi 小于等于给 S S S 赋值的初始距离 d i s S dis_S disS

考虑最短路求得解的特殊性:
最短路求得差分约束的解满足为所有 x i ≤ d i s S x_i \le dis_S xidisS 的最大解.

考察差分约束建模后产生的最短路树,若将任意某些 x i + 1 x_i+1 xi+1,则必定存在其某个 x i x_i xi 最短路树上的父亲与 x i x_i xi 不满足三角形不等式.

同理,最长路求得的解是满足所有 x i ≥ d i s S x_i \ge dis_S xidisS 的最小解.

Dijkstra

适用于非负权图最短路.
每次选择距离最短的节点,将其标记为已经求解了最短路的节点,然后用其更新其他没有标记的节点.

在非负权图中,对于一种最短路树,可以保证其父亲的距离一定小于等于自身的距离.归纳法即可证明 Dijkstra 算法的正确性.

值得注意,使用堆优化的 Dijkstra 的算法时间复杂度为 O ( m log ⁡ m ) O(m\log m) O(mlogm).当 m m m 接近 n 2 n^2 n2 时,使用不加堆优化的 Dijkstra 算法更优,复杂度为 O ( n 2 ) O(n^2) O(n2)

01 Bfs

是 Dijkstra 算法在特殊图上的一种变式.
考虑一张图只有 0 / 1 0/1 0/1 两种边权.我们使用 deque 进行 Bfs.每次取出队头,若碰到 0 0 0 边,将新节点放入对头;若碰到 1 1 1 边,将新节点放入队尾.
结论:第一次被更新时的距离即是每个节点的最短距离.

目前没有找到比较好的证明.

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值