图论 学习笔记(省选+)

网络流

最大流问题(Maximum Flow Problem)
有向有权图
给定起点s和终点t
预期:求出从s到t的最大流
ps.有些“管道”达不到其最大容量

朴素的匹配算法(Naive Algorithm):未必能找到最大流,其结果往往比最优解差一点,但是其他更好的算法都基于此算法
构建一个和原图(Original Graph)相同的新图(Residual Graph),在新图上找出一条从s到t的简单无环图(Augmenting path),可以通过例如当做无权图然后求最短路的方式
由于短板效应,这条路径上的最大流量是边权的最小值 Flow = Capacity - Residual;
然后将新图的该路径上都减少这个数字,然后按照此规则进行迭代
找不到路径时,终止程序,最大流即为减少的数字之和;某条边的流量即为上述 Flow
(算法)不漏水时,流出等于流入
由于该图是有向图,具有不可逆性,算法不能反悔,因而结果不一定是最优解
Naive求出的不一定是最大流,求出的被称为阻塞流(Blocking Flow)
阻塞流:有了这些流量,就不能增加到终点的流量了;虽然它不是最优的,但是把管道都给堵住了;最大流也是阻塞流

Ford-Fulkerson Algorithm:正确性有保障,一定能找到最大流
主要流程和朴素算法相似,但是在选择简单无环图、使此路径同时减小x之后,需要构建权值为x的反向路径;这样可以使之前选择的路径即使不好也可以撤销(构建反向路径时,不能和已有正向路径抵消。但是可以和同为反向路径的边叠加)
时间复杂度:
每次循环增加一,所以不可能超过最大流的大小。故每次的耗时为Amount of Max
设有m条边,每次找一条从起点到终点的路径(需要O(m)),因此每次循环的时间复杂度为O(m);设最大流为f,则时间复杂度为O(m*f)
一个好的算法的时间复杂度不应当依赖于最大流的大小

Edmonds-Karp Algorithm
是Ford-Fulkerson Algorithm的特例,时间复杂度不需要依赖于最大流的大小
二者的唯一区别是,Edmonds-Karp Algorithm寻找简单无环图时,需要将图看做无权图,然后寻找最短路
时间复杂度:
设m是边数,n是节点数
每一次循环需要在residual graph(最多有2m条边)上寻找最短路,时间复杂度为O(m)
循环次数最多为 m*n 轮
故总时间复杂度为:O(\(m^2\) *n),此算法不依赖于最大流的大小

Dinic's Algorithm
阻塞流(Blocking Flow):有了这些流量,管道就无法通过更多的流了;最大流一定是阻塞流,但是阻塞流不一定是最大流
naive algorithm一定能找到阻塞流
Level Graph:类似于生物中食物链中的营养级
时间复杂度:O(m*\(n^2\) )
由于在一个连通图中,节点数一般不会大于边数,故此算法更优
Dinic's Algorithm:
1.构建level graph
2.在level graph中寻找blocking flow(可以用简单算法)
3.在原图中将流量减少level graph中阻塞流中的流量得到residual graph,同时添加反向边
4.用residual graph构造新的level graph‘,然后寻找阻塞流;再从residual graph中减少阻塞流相应的流量并构建反向边,和之前的反向边合并
5.依次迭代。直到levelgraph中找不到阻塞流。原图减去最后的residual graph即为最大流 ( flow=capasity-residual)
时间复杂度:最多循环n-1次,每次时间复杂度为O(mn),故总时间复杂度为O(m*\(n^2\) )


最小割问题(Minimun Cut Problem)
最大流和最小割是等价的
S-T Cut:把集合V分成两个集合S和T
集合S和T的并集是集合V,交集是空集
其中s∈S,t∈T
二元组pair(S,T)即为s-t cut
Capacity(S,T):所有从S通向T的边的权重之和
最小割:在所有s-t cut中最小的一个(用最小的花费去截断水流)
最小割并不唯一
Max-Flow Min-Cut Theorem:最大流=最小割

求出最小流的方法:
1.用任意算法求出最大流(Edmonds-Karp algorithm和Dinic's algorihtm都可以)
2.抹去residual graph中的反向边
寻找minimum s-t
1.在residual graph中,从起点s出发,能经过的所有节点构成集合S
2.剩余的点即属于集合T


Bipartite Graph(二部图/二分图)

定义:将一个图划为两个部分,包括点集U、点集V和所有边的集合E,所有边都是U和V之间的,集合U、V的内部分别不能有边
示例:岗位分配,宠物分配,相亲大会
可以是有向图,也可以是无向图

判断是否是二部图:
1.将任意一个节点染成红色
2.将红色相邻的边染成蓝色
3.将蓝色相邻的边染成红色
4.依次迭代。如果发现一个节点和它邻居的颜色相同,则停止循环,不是二部图;如果自始至终没有出现上述情况,则是二部图
算法具体实现:
准备一个空队列queue;任意标记一个节点\(v_1\),将它放入队列;
取出队顶 ,查看邻边;
如果未被访问:
染成异色,放入队列;
如果被访问过:
如果同色,则不冲突,继续循环;
如果异色,结束循环,非二部图;结束程序。
如果队列为空,停止循环,是二部图;结束程序。
如果有未被染色,删除已经染色的部分,重复之前的操作,如果true,则也是二部图;
时间复杂度:O(|V|+|E|)

无权图的二分图匹配问题Maximum-Cardinality Bipartite Matching(MCBM)
边的匹配:一个边的集合,可以使每一个节点连接不超过一条边(边不能有共同节点)
MCBM的定义:在所有匹配中,权值和最大的一种匹配;由于是无权图,所有匹配数即为匹配数
转化:新增两个点,分别是source(点s)和sink(点t);构建两组新边,分别从点s指向所有的点集U中的元素,从点t指向所有的点集V中的元素。把所有边的流量设为1。

有权图的二分图匹配问题
把集合U中的元素和集合V中的元素之间的边记为\(w_{ij}\),把图表示为邻接矩阵
应用:让合适的人做合适的工作,收养更喜欢的宠物,找合适的对象
最大匹配和最小匹配是可以相互转化的,将边正权全部取反进而转化为负权,而结果是相同的;
匈牙利算法(Hungarian Algorithm):寻找最小匹配
要求:两边的节点数相同(都为n),一般用邻接矩阵来存图
初始化:对于每一个集合U中的节点,设它连接的权重最小的边权为x。将所有和它相连的边权都减少x,这时邻接矩阵中每一行都至少有一个0;再对每一个集合V中的节点做相同的操作;最终每一行每一列都至少有一个0。
对于每一次循环:
1.找一些线(横着或者竖着的)来覆盖所有的0;
2.决定停止程序:如果需要n条线,则停止循环;如果需要线数少于n,则继续循环;
3.创造额外的0:在所有非0元素中寻找最小的元素,记作x;把所有没有线覆盖的数字都减去x,把所有线交叉地方的数字都增加x。
终止循环后,0的数量即为边数,从中选出n个作为最小匹配,即为答案。

稳定婚配问题(stable marriage)
一组男和一组女(元素数量都为n),每个人分别对对方组别的每一个人有排序;每个人心中的男神或者女神不一定是配偶,假如一男一女不是配偶,而且相互之间的爱超过了对彼此配偶的爱,那么他们都会选择离婚,然后组建新的家庭;即每个人都追不到比自己配偶更好的对象
稳定婚配并不唯一
Gale-Shapley Algorithm(对主动方更有利的策略)
1.寻找一个未婚男性向他最喜欢的女性求婚,即使此女性已婚也没关系;但是如果这个女性已经拒绝过他,那就向下一个女性求婚(好马不吃回头草),即向一个人不能求婚两次
2.女性在offer中选择出最喜欢的那一个;如果已婚,并且offer更好,那就可以换个配偶
时间复杂度:O(\(n^2\))

posted @ 2023-06-25 19:16  欢黎明陌  阅读(86)  评论(0编辑  收藏  举报