CTRL+F使用之
图论 Graph Theory
定义与术语 Definition and Glossary
图与网络 Graph and Network
二元组称为图(graph).为结点(node)或顶点(vertex)集.为中结点之间的边的集合.
点对称为边(edge)或称弧(arc),其中,称是相邻的(adjacent),称u,v与边相关联(incident)或相邻.
若边的点对有序则称为有向(directed)边,其中u称为头(head),v称为尾(tail).所形成的图称有向图(directed graph).为对于u来说是出边(outgoing arc);对于v来说是入边(incoming arc).反之,若边的点对无序则称为无向(undirected)边,所形成的图称无向图(undirected graph).
若图的边有一个权值(weight),则称为赋权边,所形成的图称赋权图(weighted graph)或网络(network).用三元组G(V,E,W)表示网络.其中W表示权集,它的元素与边集E一一对应.
满足的图,称为稀疏(sparse)图;反之,称为稠密(dense)图.
图的术语 Glossary of Graph
阶(order):图G中顶点集V的大小称作图G的阶.
环(loop):若一条边的两个顶点为同一顶点,则此边称作环.
简单图(simple graph):没有环,且没有多重弧的图称作简单图.
定向图:对无向图G的每条无向边指定一个方向得到的有向图.
底图:把一个有向图的每一条有向边的方向都去掉得到的无向图.
逆图:把一个有向图的每条边都反向由此得到的有向图.
竞赛图(tournament):有向图的底图是无向完全图,则此有向图是竞赛图.
邻域(neighborhood):在图中与u相邻的点的集合,称为u的邻域,记为.
度:
度(degree):一个顶点的度是指与该边相关联的边的条数,顶点v的度记作deg(v).握手定理:无向图:;有向图:.
入度(indegree):在有向图中,一个顶点v的入度是指与该边相关联的入边(即边的尾是v)的条数,记作.
出度(outdegree):在有向图中,一个顶点的出度是指与该边相关联的出边(即边的头是v)的条数,记作.
孤立点(isolated vertex):度为0的点.叶(leaf):度为1的点.
源(source):有向图中,=0 的点.汇(sink):有向图中,=0的点.
奇点(odd vertex):度为奇数的点.偶点(even vertex):度为偶数的点.
子图:
子图(sub-graph):G'称作图G的子图如果以及.
生成子图(spanning sub-graph):即包含G 的所有顶点的连通子图,即满足条件的G的子图G'.
生成树(spanning tree):设T是图G的一个子图,如果T是一棵树,且,则称T是G的一个生成树.即G的生成子图,且子图为树.
点导出子图(induced subgraph):设,以为顶点集,以两端点均在中的边的全体为边集所组成的子图,称为G的由顶点集导出的子图,简称为G的点导出子图,记为.
边导出子图(edge-induced subgraph):设,以为顶点集,以两端点均在中的边的全体为边集所组成的子图,称为G的由边集导出的子图,简称为G的边导出子图,记为.
图的补图(complement):设G是一个图,以为顶点集,以为边集的图称为G的补图,记为.
点集的补集:记 为点集的补集.
特殊的图:
零图(null graph):,即只有孤立点的图.n阶零图记为.
平凡图(trivial graph):一阶零图.
空图(empty graph):的图.
有向无环图(directed acyclic graph(DAG)):有向的无环的图.
完全图(complete graph):完全图是指每一对不同顶点间都有边相连的的无向图,n阶完全图常记作.
二分图(bipartite graph):若图G的顶点集可划分为两个非空子集X和Y,即且,且每一条边都有一个顶点在X中,而另一个顶点在Y中,那么这样的图称作二分图.
完全二分图(complete bipartite graph):二分图G中若任意两个X和Y中的顶点都有边相连,则这样的图称作完全二分图.若,则完全二分图G记作.
正则图(regular graph):如果图中所有顶点的度皆相等,则此图称为正则图.
路径与回路 Path and Cycle
途径(walk):图G中一个点边交替出现的序列,满足,.
迹(trail):边不重复的途径.
路(path):顶点不重复的迹.
简单图中的路可以完全用顶点来表示,.
若,称闭的(closed);反之,称为开的(open).
闭途径(closed walk):起点和终点相同的途径.
闭迹(closed trail):起点和终点相同的迹,也称为回路(circuit).
圈(cycle):起点和终点相同的路.
途径(闭途径),迹(闭迹),路(圈)上所含的边的个数称为它的长度(length).
简单图G中长度为奇数和偶数的圈分别称为奇圈(odd cycle)和偶圈(even cycle).
对任意,从x到y的具有最小长度的路称为x到y的最短路(shortest path),其长度称为x到y的距离(distance),记为.
图G的直径(diameter):.
简单图G中最短圈的长度称为图G的围长(girth),最长圈的长度称为图G的周长(perimeter).
连通性 Connectivity
连通(connected):在图G中,两个顶点间,至少存在一条路径,称两个顶点连通的(connected);反之,称非连通(unconnected).
强连通(strongly connected):在有向图G中,两个顶点间,至少存在一条路径,称两个顶点强连通.
弱连通(weakly connected):在有向图G中,两个顶点间,若不考虑G中边的方向的图才连通的,称原有向图为弱连通.
连通图(connected graph):图G中任二顶点都连通.
连通分量或连通分支(connected branch, component):非连通无向图的极大连通子图(maximally connected sub-graph).具体说,若图G的顶点集V(G)可划分为若干非空子集,使得两顶点属于同一子集当且仅当它们在G中连通,则称每个子图为图G的一个连通分支().图G的连通分支是G的一个极大连通子图.图G连通当且仅当.
强连通分量(strongly connected branch):非强连通图有向图的极大强连通子图.
割(cut):
点割集(vertex cut):点集,若G删除了后不连通,但删除了的任意真子集后G仍然连通.则称点割集.若某一结点就构成就了点割集,则称此结点割点(cut vertex).点数最少的点割集称为点连通度k(G).
边割集(edge cut set):边集,若G删除了后不连通,但删除了的任意真子集后G仍然连通.则称点割集.若某一边就构成就了边割集,则称此结点割边(cut edge)或桥(bridge).边数最少的边割集称为边连通度k'(G).
记号表示一端在S中另一端在中的所有边的集合.
块(block)是指没有割点的极大连通子图.
图论中特殊的集合 Sets in graph
点覆盖(集)(vertex covering (set)):,满足对于,有,关联.即一个点集,使得所有边至少有一个端点在集合里.或者说是"点" 覆盖了所有"边".极小点覆盖(minimal vertex covering):本身为点覆盖,其真子集都不是.最小点覆盖(minimum vertex covering):点最少的点覆盖.点覆盖数(vertex covering number):最小点覆盖的点数,记为
一般说覆盖集就是指点覆盖集.
边覆盖(集)(edge covering (set)):,满足对于,有,关联.即一个边集,使得所有点都与集合里的边邻接.或者说是"边" 覆盖了所有"点". 极小边覆盖(minimal edge covering):本身是边覆盖,其真子集都不是.最小边覆盖(minimum edge covering):边最少的边覆盖.边覆盖数(edge covering number):最小边覆盖的边数,记为.
独立集(independent set):,满足对于,有.即一个点集,集合中任两个结点不相邻,则称为独立集.或者说是导出的子图是零图(没有边)的点集.极大独立集(maximal independent set):本身为独立集,再加入任何点都不是.最大独立集(maximum independent set):点最多的独立集.独立数(independent number):最大独立集的点数,记为.
团(clique):,满足对于,有.即一个点集,集合中任两个结点相邻.或者说是导出的子图是完全图的点集.极大团(maximal clique):本身为团,再加入任何点都不是.最大团(maximum clique):点最多的团.团数(clique number):最大团的点数,记为.
边独立集(edge independent set):,满足对于,有不邻接.即一个边集,满足边集中的任两边不邻接.极大边独立集(maximal edge independent set):本身为边独立集,再加入任何边都不是.最大边独立集(maximum edge independent set):边最多的边独立集.边独立数(edge independent number):最大边独立集的边数,记为.
边独立集又称匹配(matching),相应的有极大匹配(maximal matching),最大匹配(maximum matching),匹配数(matching number).
支配集(dominating set):,满足对于,有,.即一个点集,使得所有其他点至少有一个相邻点在集合里.或者说是一部分的"点"支配了所有"点". 极小支配集(minimal dominating set):本身为支配集,其真子集都不是.最小支配集(minimum dominating set):点最少的支配集.支配数(dominating number):最小支配集的点数,记为.
边支配集(edge dominating set):,满足对于,有,邻接.即一个边集,使得所有边至少有一条邻接边在集合里.或者说是一部分的"边"支配了所有"边".极小边支配集(minimal edge dominating set):本身是边支配集,其真子集都不是.最小边支配集(minimum edge dominating set):边最少的边支配集.边支配数(edge dominating number):最小边支配集的边数,记为.
定理:若G中无孤立点,D为支配集,则D=V(G)-D也是一个支配集.
定理:一个独立集是极大独立集,当且仅当它是支配集.
关系:
定理:无向图G无孤立点,是极小支配集,则存在是极小支配集,且.
定理:无向图G无孤立点,是极大独立集,则是极小支配集.逆命题不成立..
定理:连通图中,是点覆盖,则是支配集.极小点覆盖不一定是极小支配集.支配集不一定是点覆盖.
定理:无向图G无孤立点,是(极,最小)点覆盖,充要于是(极,最大)独立集..
定理:无向图G,是G的(极,最大)团,充要于是的(极,最大)独立集..
由上述定理知,,,三者互相确定,但都是NPC的.但是二分图中,点覆盖数是匹配数.
M是匹配,W是边覆盖,N是点覆盖,Y是点独立集.
定理:无向图G无孤立点,|M|<=|N|,|Y|<=|W|
定理:无向图G无孤立点,.先取一个最大匹配M,1条边盖两个点;剩下的一个未盖点要用一条边来覆盖,边覆盖数=|M| +(|V|-2|M|)= |V|-|M|.
定理:无向图G无孤立点,=,=.
定理:无向图G无孤立点,=.
求匹配数是P的,所以边覆盖和匹配都是易求的.
最小路径覆盖(path covering):是"路径" 覆盖"点",即用尽量少的不相交简单路径覆盖有向无环图G的所有顶点,即每个顶点严格属于一条路径.路径的长度可能为0(单个点).
最小路径覆盖数=G的点数-最小路径覆盖中的边数.应该使得最小路径覆盖中的边数尽量多,但是又不能让两条边在同一个顶点相交.拆点:将每一个顶点i拆成两个顶点Xi和Yi.然后根据原图中边的信息,从X部往Y部引边.所有边的方向都是由X部到Y部.因此,所转化出的二分图的最大匹配数则是原图G中最小路径覆盖上的边数.因此由最小路径覆盖数=原图G的顶点数-二分图的最大匹配数便可以得解.
匹配 Matching
匹配(matching)是一个边集,满足边集中的边两两不邻接.匹配又称边独立集(edge independent set).
在匹配中的点称为匹配点(matched vertex)或饱和点;反之,称为未匹配点(unmatched vertex)或未饱和点.
交错轨(alternating path)是图的一条简单路径,满足任意相邻的两条边,一条在匹配内,一条不在匹配内.
增广轨(augmenting path):是一个始点与终点都为未匹配点的交错轨.
最大匹配(maximum matching)是具有最多边的匹配.
匹配数(matching number)是最大匹配的大小.
完美匹配(perfect matching)是匹配了所有点的匹配.
完备匹配(complete matching)是匹配了二分图较小部份的所有点的匹配.
增广轨定理:一个匹配是最大匹配当且仅当没有增广轨.
综上,在二分图中,最小覆盖数=最大匹配数.边覆盖数=最大独立数=|V|-最大匹配数.
树 Tree
G=(V, E)为一个图,则下列命题等价:(1)G是一棵树;(2)G连通,且|E|=|V|-1;(3)G无圈,且|E|=|V|-1;(4)G的任何两个顶点之间存在唯一的一条路;(5)G连通,且将G的任何一条弧删去之后,该图成为非连通图;(6)G无圈,且在G的任何两个不相邻顶点之间加入一条弧之后,该图正好含有一个圈.
Cayley公式:在n阶完全图中,不同生成树的个数为.
组合优化 Combinatorial optimization
从若干可能的安排或方案中寻求某种意义下的最优安排或方案,数学上把这种问题称为(最)优化(optimization)问题.
所谓组合(最)优化(combinatorial optimization)又称离散优化(discrete optimization),它是通过数学方法去寻找离散事件的最优编排,分组,次序或筛选等. 这类问题可用数学模型描述为:
其中D表示有限个点组成的集合(定义域),f为目标函数,为可行域.
网络优化(network optimization)就是研究与(赋权)图有关的组合优化问题.
常见的P类网络优化问题:最小生成树,最短路,最大流,最小费用最大流,最大匹配,中国邮路问题.
常见的NP类网络优化问题:旅行商问题.
参考文献:
[1]Dictionary of Algorithms and Data Structures NIST,http://www.nist.gov/dads/
[2]Wikipedia,http://en.wikipedia.org/wiki/Graph_theory
[3]谢金星,清华大学数学科学系<>讲义
http://faculty.math.tsinghua.edu.cn/~jxie/courses/netopt
图的表示 Expressions of graph
下面介绍几种表示图的数据结构.并统一用下图做例子:
邻接矩阵 Adjacency matrix
用二元数组,来表示图.这种表示法一般用于稠密图.当图不是简单图,邻接矩阵法不能用.
在无权图中,若边存在,=1;否则=0.
无权图的例子:
在有权图中, 若边存在,则为它的权值;否则人为的规定=∞或-∞.∞是一个足够大的数.
无向图中,邻接矩阵是按矩阵副对角线对称的.
关联矩阵 Incidence matrix
用二元数组,来表示无权有向图.一般不用这种表示法.
若边k与点u关联,若k是u的出边,则=1;若k是u的入边=-1;否则=0.
无权图的例子:
邻接表 Adjacency list
图的邻接表是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所有出弧的集合,含有终点,权值等信息.
对于有向图G=(V,E),一般用A(v)表示节点v的邻接表,即节点v的所有出弧构成的集合或链表(实际上只需要列出弧的另一个端点,即弧的尾).
一般图都适用.邻接表方法增加或删除一条弧所需的计算工作量很少.
有权图的例子:A(1)={2,3},A(2)={4},A(3)={2},A(4)={3,5},A(5)={3,4}
弧表 Arc list
所谓图的弧表, 也就是图的弧集合中的所有有序对以表格的方式来表示.弧表表示法直接列出所有弧的起点和终点,以及权值.一般用于稀疏图.缺点是无法通过一些信息(起点,终点)定位一条边.
用S(i),F(i),W(i)分别表示起点,终点,权值.
有权图的例子:
起点
1
3
4
5
5
4
2
1
终点
2
2
5
4
3
3
4
3
权值
8
4
3
7
6
0
6
9
星形表示 Star
星形表示法就是对弧表的缺点的改进,使之可以通过起点或终点定位边.由于很多时候,算法只需事先知道起点,通过枚举边扩展,而不需要事先知道终点;如图的遍历,松弛操作.
按定位方式,又分前向星形(forwards star)与反向星形(reverse star).前向星形:通过起点定位边.反向星形:通过终点定位边.实际上,反向星形几乎没用.故本文只讨论前向星形.
通常有两种方法实现这种对弧表改进:边排序法,链表法.
边排序法:把弧表按起点为第一关键字,终点为第二关键字来排序.排序用不用额外空间的快速排序O(mlogm)或用额外空间O(m)的计数排序O(m)均可.之后用数组last(u)记录以结点u为起点的最后一条边的编号,并规定last(0)=0.这样以结点u为起点的边编号就是last(u-1)+1到last(u).有权图的例子:
链表法:给每条边(u,v)加一个前趋,表示以u为起点的边链表的前一条边.直观的讲,就是将相同结点的边用链表串起来.last(u)存以u为起点的最后一条边的编号.有权图的例子:
星形表示法的优点是占用的存贮空间较少.一般图都适用.边排序法的优点是已知起点和终点的情况下可以精确定位边,容易在起点定位的范围内二分查找终点,在反向边的定位中常用;缺点是代码麻烦,时间抑或空间上都有额外开销.链表法的优点很多,不仅代码简单,而且没有太多的时空开销,对于反向边的定位只要多加一个数据项纪录下反向边即可;除了终点定位性,几乎没缺点.
参考文献:
[1]谢金星,清华大学数学科学系<>讲义
http://faculty.math.tsinghua.edu.cn/~jxie/courses/netopt
[2]刘汝佳,黄亮,<>,P60
图的遍历 Traveling in graph
深度优先搜索 Depth first search (DFS)
概念
求无向连通图中的桥 Finding bridges in undirected graph
在无向连通的条件下,边是桥的充要条件是:1.桥一定是DFS树中的边;2.桥一定不在圈中.
圈是由一条后向边(u,v)与DFS树中u到v的路径组成.也就是说u到v的路径上的边都不可能是桥,应该给以标记.记f(x)为x与其子孙的后向边所连到的最老祖先(深度最浅),表示x 到f(x) 上的边均不为桥.然而维护f(x)比较麻烦,其实只要知道f(x)的拓扑序数就可以了.所谓拓扑序数就是满足儿子的序数总比父亲大的一个编号方式.这个拓扑序,常用使用深度d,或者使用时间戳(TimeStamp) DFN(DFS访问的次序).下面以深度为例:
记,在DFS树中从x开始通过前向弧和后向弧所能到达的最小的d.有以下的动态规划:
这里:
1.第一次访问x时,记录d(x)
2. d(y)自己发出去的后向边所达到的深度.
3. g(c)就是其子孙中的g最小值.
最后,若g(x)=d(x),即(father,x)不在圈中,则(father, x)就是桥.
广度优先搜索 Breadth first search (BFS)
拓扑排序 Topological sort
拓扑排序是对有向无圈图(DAG)顶点的一种排序,它使得如果存在u,v的有向路径,那么满足序中u在v前.拓扑排序就是由一种偏序(partical order)得到一个全序(称为拓扑有序(topological order)).偏序是满足自反性,反对称性,传递性的序.
拓补排序的思路很简单,就是每次任意找一个入度为0的点输出,并把这个点以及与这个点相关的边删除.实际算法中,用一个队列实现.
算法:
把所有入度=0的点入队Q.
若队Q非空,则点u出队,输出u;否则转4.
把所有与点u相关的边(u,v)删除,若此过程中有点v的入度变为0,则把v入队Q,转2.
若出队点数m,结束,此时G没有生成树;否则判断是否含圈,是则转2,否则转3.
.若|T|=N,结束,此时T为G的最小生成树.
分离集合(disjoint set),可用并查集实现.由于排序是的.所以复杂度为.
Sollin(Boruvka)
基本思想:前面介绍的两种算法的综合.每次迭代同时扩展多棵子树,直到得到最小生成树 T.
算法:
对于所有..
若|T|=N,结束,此时T为G的最小生成树;否则,对于T中所有的子树集合,计算它的边割中的最小弧(有的书称连接两个连通分量的最小弧"安全边").
对T中所有子树集合及其边割最小弧,将与q所在的子树集合合并..转2.
由于每次循环迭代时,每棵树都会合并成一棵较大的子树,因此每次循环迭代都会使子树的数量至少减少一半,或者说第i次迭代每个分量大小至少为.所以,循环迭代的总次数为O(logn).每次循环迭代所需要的计算时间:对于第2步,每次检查所有边O(m),去更新每个连通分量的最小弧;对于第3步,合并个子树.所以总的复杂度为.
扩展模型 Extended models
度限制生成树 Minimum degree-bounded spanning trees
由于这个问题是NP-Hard的,一般用搜索算法解决.本文就只讨论一种特殊多项式情况:单点度限制(one node degree bounded).
把度限制的点记为,满足度限制.一种贪心的思路:在最小生成树T的基础上,通过添删边来改造树,使之逐渐满足度限制条件.
算法:
求图的最小生成树T.
若已满足度限制,结束;否则转3.
对于删去后的每一个连通分支(为一棵树),求添加边割中的最小弧,删除边割里的最大弧后的生成树中的边权和最小的一个.更新最小生成树T.转2.
第3步,的度少1.
习题:NOI 2005 小H的聚会
k小生成树 The k minimum spanning tree problem(k-MST)
生成树T删除一条边f并加入一条新边e的操作称为交换.若交换后的图仍是一颗树,则此交换称为可行交换.若生成树T可通过一次交换成为生成树T',则称它们互为邻树.对于生成树集合S,生成树T,若T不在S中,且在S中存在某生成树是T的邻树,称为T为S的邻树.
定理:设为图的前k小生成树,则生成图集合的邻树中的边权和最小者可作为第k+1小生成树(可能有边权和相同的情况).
按这个定理设计算法,很难得到有满意的时间复杂度的算法.
下面讨论一个特例:次小生成树(The second MST, 2-MST)
基本思想:枚举最小生成树T的每一个邻树,即枚举被添加与被删除的边.由于在树中添加一条边(),一定形成了一个环,环是由与从u到v的生成树上的唯一路径(记为)组成的.所以被删除的边一定在上.由于要求最小边权和,所以被删除的边一定是上最小者,其权值记为:.
算法:
求图的最小生成树T.次小生成树T'的权值的最小值.
以每个结点为根r,DFS遍历树.在遍历过程中求出,用更新次小生成树的权值的最小值.
输出.
算法复杂度的瓶颈在第2步,故总算法复杂度为.
习题:Ural 1416 Confidential
最短路Shortest paths
单源最短路 Single-source shortest paths
令s为起点,t为终点.单源最短路问题定义为:对于网络G=(V,E,W),寻找s到t的一条简单路径,使得路径上的所有边权和最少.令d(v)为s到v的最短路长度上界.单源最短路问题的规划模型如下:
对于只含正有向圈的连通有向网络,从起点s到任一顶点j都存在最短路,它们构成以起点s为根的树形图(称为最短路树(Tree of Shortest Paths)).当某弧(u,v)位于最短路上时,一定有.所以最短路的长度可以由Bellman方程(最短路方程)唯一确定:
在规划模型与最短路方程中都出现了形式的式子,下面引入松弛操作:松弛操作是对于边(u,v)进行的改进操作:若,则改进.直观的讲,就是路径最后通过(u,v),使得s到v的距离比原来s到v的方案的距离短.松弛操作是最短路算法求解的基本方式.
最短路算法求解过程中的标号规定:对于V 中每一个顶点v,设置一个标号:距离标号d(v) ,记录的是从起点到该顶点的最短路长度的上界;再设置一个是前趋pred(v),记录的是当起点s到该顶点v的一条路长取到该上界时,该条路中顶点v 前面的那个直接前趋.算法通过不断修改这些标号,进行迭代计算.当算法结束时,距离标号表示的是从起点到该顶点的最短路长度.
标号设定算法(Label-Setting):在通过迭代过程对标号进行逐步修正的过程中,每次迭代将一个顶点从临时标号集合中移入永久标号集合中.
标号修正算法(Label-Correcting):每次迭代时并不一定将任何顶点标号从临时标号转变为永久标号,只是对临时标号进行一次修正,所有顶点标号仍然都是临时标号;只有在所有迭代终止时,所有顶点标号同时转变为永久标号.
最长路问题可以转化为最短路问题,把弧上的费用反号即可.
基本算法 Basic algorithms
Dijkstra
采用了标号设定算法(Label-Setting).在迭代进行计算的过程中,所有顶点实际上被分成了两类:一类是离起点较近的顶点,它们的距离标号表示的是从点s到该顶点的最短路长度,因此其标号不会在以后的迭代中再被改变(称为永久标号);一类是离起点较远的顶点,它们的距离标号表示的只是从点到该顶点的最短路长度的上界,因此其标号还可能会在以后的迭代中再被改变(称为临时标号).下文称永久标号为已检查.
算法:
1. ,,已检查
2. 取未检查的u,即,使得最小.若u取不到,即d(u)=∞则结束;否则标记为已检查,即.
3. 枚举所有的u的临边,满足v未检查,即.松弛,即若,则改进,pred(v)=u.转2.
这里的d可以用优先队列实现,需用到删除最小(DeleteMin)与减值(DecreaseKey)的操作.假设用Fibonacci Heap实现(删除最小O(logn),减值O(1)),则算法复杂度:.若用Binary Heap则.
适用范围:非负权图.
Bellman-Ford
采用了标号修正算法(Label-Correcting).本质就是用迭代法(动态规划)解Bellman-Ford方程:
表示s到v的且边数不超过k条时的最短路路长.下面用归纳法证明:k=1显然成立.假设对k成立,下面考虑k+1的情况.从起点s到顶点v且所经过的弧数不超过k+1条时的最短路有两种可能:含有不超过k条弧,即;含有k+1条弧,即.
由于第k+1次迭代过程中,不会影响k次的迭代结果,d用O(n)的空间即可.
算法:
,
松弛所有边(u,v),即若,则改进,pred(v)=u.若没有边被松弛,则算法结束.
若2的迭代次数超过n-1,则有负权圈,结束;否则转2继续迭代.
可以证明算法一定在n-1步迭代后收敛;否则一定有负权圈.所以算法复杂度为O(nm).
适用范围:一般图.
Shortest path faster algorithm(SPFA)
SPFA 其实就是Bellman-Ford的一种队列实现,减少了冗余,即松驰的边至少不会以一个d为∞的点为起点.
算法:
队列Q={s},,
取出队头u,枚举所有的u的临边.若,则改进,pred(v)=u,由于减少了,v可能在以后改进其他的点,所以若v不在Q中,则将v入队.
一直迭代2,直到队列Q为空(正常结束),或有的点的入队次数>=n(含有负圈).
由于点可能多次入队,但队列中同时不会超过n个点.所以用一个长度为n的循环队列来实现这个队.
SPFA在形式上和宽度优先搜索非常类似,不同的是宽度优先搜索中一个点出了队列就不可能重新进入队列,但是SPFA中一个点可能在出队列之后再次被放入队列,也就是一个点改进过其它的点之后,过了一段时间可能本身被改进,于是再次用来改进其它的点,这样反复迭代下去.设一个点用来作为迭代点对其它点进行改进的平均次数为k,有办法证明对于通常的(不含负圈,较稀疏)情况,k在2左右.算法复杂度理论上同Bellman-Ford,O(nm),但实际上却是O(km).
一般用于找负圈(效率高于Bellman-Ford),稀疏图的最短路.
习题:Ural 1254 Die Hard (可斜走的网格最短路).
应用Applications
差分约束系统 System of difference constraints
差分约束系统:求解n个未知数,满足m个不等式:
若描述为线形规划模型:.矩阵A每行含一个1一个-1,其他都是0.
如线形规划模型
等价于
注意到单源最短路模型中的.,即.很像差分约束系统模型.于是可以构造一个有向网络G=(V,E,W),称为约束图(constraints graph).
.
W:,
对进行Bellman-Ford算法,可以得到,令,即为所求,其中C是任意一个常数,均满足原不等式组.当有为负数且题目要求非负时,常常令C为最小的的相反数.
习题:NOI 1999 01串
有向无环图上的最短路 Shortest paths in DAG
算法:
1. ,.对有向无环图G,拓扑排序O(m).
2.按拓扑序枚举u.若枚举完,则结束.
3.枚举所有u的临边(u,v),对(u,v)进行松弛操作,即若,则改进,pred(v)=u.转2.
复杂度:
所有顶点对间最短路 All-pairs shortest paths
基本算法 Basic algorithms
Floyd-Warshall
本质就是用迭代法(动态规划):
表示u到v的不经过k,k+1,…,n结点(除u,v外)时,从u,v的最短路长.下面用归纳法证明:k=1显然成立.假设对k成立,下面考虑k+1的情况;从u到v 且不通过k+1,…, n 节点的最短路有两种可能:(1)不经过k节点,即为;(2)经过k节点,即为.
由于第k+1次迭代过程中,不会影响k次的迭代结果,d用的空间即可.二维数组,记录u到v,最后经过哪个k的迭代.
算法:
k=1,对于所有u,v ,
k=k+1,对于所有u,v,若,则,.若发现某个节点u使得, 则说明网络本来就含有负有向圈,结束.
若k=n,结束;否则转2.
算法复杂度:
Johnson
本算法适用于稀疏图.它是Dijkstra和Bellman-Ford算法的综合应用.
本算法用了权值改造(reweighting)技术.若图的权值非负,则对于每个结点用一次Dijkstra算法,就可以求出所有顶点对间最短路.若图中有负权,但没有负圈,则可以把权值W改造成W',W'非负,使得能够使用Dijkstra算法.
算法:
给图G,加一个新结点.对用Bellman-Ford,若有负圈,则结束;否则可以得到,即到的最短路长.O(nm)
对于所有边,权值改造,即令.O(m)
对于每个结点,用一次以Fibonacci Heap为优先队列的Dijkstra算法,可求出与其他顶点的最短路.O(nlogn+m)*O(n)
算法总复杂度.
权值改造满足两个原则:(1)W' 非负;(2)对于任意顶点u, v,p是在W上的u到v的最短路当且仅当p是在W'上的u到v的最短路.下证,满足以上两个原则:
(1)由于h是v0到v的最短路长,,所以.
(2)令路径,则
只与以及首尾的标号h有关,不影响的决策.所以是最短路长当且仅当是最短路长,且不影响最短路p.
参考文献:
[1] 25.3 Johnson's algorithm for sparse graphs,Introduction to Algorithms,MIT Press
网络流 Flow network
最大流 Maximum flow
在有向无权图G(V,E,C)中,其中C为每条边的容量(capability),再给每条边赋予一个流值(flow),并规定源s和汇t.最大流问题的数学模型描述如下:
其中(2),为容量限制条件:边的流量不超过边上的容量.
其中(3)规定反向边的流量为正向边的流量的相反数.
其中(4)可以改写成:
称为流量平衡条件.它表示除了源s和汇t外的结点流入等于流出.
其中(1)表示要求从源流出的流量要最大.
最小切割最大流定理:s-t 最大流流值=s-t最小切割容量.
习题:Ural 1277 Cops and Thieves (最小切割最大流)
基本算法 Basic algorithms
Ford-Fulkerson method
增广轨定理:
Edmonds-Karp algorithm
Minimum length path
Maximum capability path
预流推进算法 Preflow push method
Push-relabel
Relabel-to-front
Dinic method
DINIC & MPM
===========
我们能够做的更快一些么
前面的算法需要O(mn)次迭代,而每次需要O(m)的时间,因此总共需要O(m^2 n).
下面我们试着降到O(n^3).
想法:假设d=d(t),我们将试着一次性的找到很多到t的长度为d的路径.为了做到
这个,我们看前面得到的层次图(我们不考虑所有的后向边以及两个端点在同一层
的边).我们现在尝试着在这个图中执行尽量多的流量,然后我们才重新计算剩余
图.
术语:一个充满了这个剩余图的流称之为块流.
因此我们的目标就是在这个剩余图中在O(n^2)的时间内找到一个块流.
我们定义c(v)=顶点v的容量:也就c_in[v],c_out[v]的最小值,这里c_in[v]是所有
v的入边的容量的和,而c_out[v]类似.
算法:
-找到具有最小容量c的顶点v.如果他的容量是0,oh yeah--我们就可以把他和与
他相关联的边都删除掉,并且更新他的邻居的容量值.
-如果c不为0,那么我们将从s运送c个单位流到v,然后从v运送到t.你可能觉得这
不又回到原来的问题了么 但是,这里有点值得注意:因为v具有最小的容量,
我们可以使用任何的贪心策略来从其他顶点流入流出c的流量而不会被堵住.这一
点意味着,我们可以在O(m)的时间内充满v.
(* daizi
nnd,想了好久才明白具体怎么做的
首先,为了从s运送c到v,我们从v开始向上考虑,把任意一条从v向上的边给充满,
如果不能够充满,说明还没有安置的流量就这些了,全部扔在这条边上就是了,
为什么一定能够找到这样一条边呢,:)
然后假设我们刚才填充的这条边是u->v,那么我们就有一些流量需要在u继续往上
进行处理,使用刚才在v点同样的办法,直到一直处理到了s,一路上肯定是不会
出现什么障碍的.
然后我们将c从v运送到t,我们在构造这个层次图的时候很容易就可以保证所有从
s出发的路径都会在t终结,这样就好办了,使用上面同样的办法,只是处理的方
向是从v到t了.
这样,我们刚才处理的过程就容易得到下面的下面所谓的性质了.
*)
上面的算法给了我们一个可以在O(mn)的时间内充满这个层次图的算法,下面进一步
分析.
为了得到我们需要的界,我们需要这样一个性质:当我们在上面的对每个新的顶点v
执行算法的步骤中,保证对每条边我们只检查一次,对其做完所有需要的操作
之后才会去做下一条边.这点意味着,我们可以把运行时间分成两个部分来考虑:
a)花在被充满的边上的时间 b)花在没有被充满的边上的时间.对于a),因为我们
每次充满一条边就会把它从图中删除,所以a)的总时间是O(m).
因此我们的时间主要由b)来决定,而b)对应的边在对每个新的顶点v的执行过程中
至多出现O(n)次,因此总的时间是O(n^2).而我们可以在O(m)的时间内重新计算新
的层次图,所以我们就可以在O(n m + n n^2)时间完成整个算法,也就是O(n^3).
扩展模型 Extended models
有上下界的流问题
问题模型:
给定一个加权的有向图,满足:
(1)容量限制条件:
(2)流量平衡条件:
(2)中的,即除了源汇外,所有点都满足流量平衡条件,则称G为有源汇网络;否则,即不存在源汇,所有点都满足流量平衡条件,则称G为无源汇网络.
将这类问题由易到难一一解决:
问题[1] 求无源汇的网络有上下界的可行流
由于下界是一条弧上的流必需要满足的确定值.下面引入必要弧的概念:必要弧是一定流要满的弧.必要弧的构造,将容量下界的限制分离开了,从而构造了一个没有下界的网络G':
将原弧(u,v)分离出一条必要弧:.(红色表示)
原弧:.
由于必要弧的有一定要满的限制,将必要弧"拉"出来集中考虑:
添加附加源x, 附加汇y.想像一条不限上界的(y, x),用必要弧将它们"串"起来,即对于有向必要弧(u, v),添加(u, y),(x, v),容量为必要弧容量.这样就建立了一个等价的网络.
一个无源汇网络的可行流的方案一定是必要弧是满的.若去掉(y, x)后,附加源x到附加汇y的最大流,能使得x的出弧或者y的入弧都满,充要于原图有可行流.
算法:
按上述方法构造新网络(分离必要弧,附加源汇)
求附加源x到附加汇y的最大流
若x的出弧或y的入弧都满,则有解,将必要弧合并回原图;否则,无解.
问题[2] 求有源汇的网络有上下界的可行流
加入边(t, s),下界为0(保证不会连上附加源汇x, y),不限上界,将问题[2]转化为问题[1]来求解.
问题[3]求有源汇的网络有上下界的最大流
算法:
先转化为问题[2]来求解一个可行流.若可行无解,则退出.由于必要弧是分离出来的,所以就可以把必要弧(附加源汇及其临边)及其上的流,暂时删去.再将(T,S)删去,恢复源汇.
再次,从S到T找增广轨,求最大流.
最后将暂时删去的下界信息恢复,合并到当前图中.输出解.
这样既不破坏下界(分离出来)也不超出上界(第2步满足容量限制),问题解决.
问题[4]求有源汇的网络有上下界的最小流
算法:
同问题[3].
从T到S找增广轨,不断反着改进.
同问题[3].
问题[3]与问题[4]的另一种简易求法:
注意问题[2]中,构造出的(t, s),上下界几乎没什么限制.下面看看它的性质:
定理:如果从s到t有一个流量为a的可行流f,那么从t到s连一条弧(t, s),其流量下界b(t, s) = a,则这个图一定有一个无源汇的可行流:除了弧(t, s)的容量为a外,其余边的容量与f相同.
证明:如果从s到t的最大流量为amax,那么从t到s连一条下界b(t, s) = a' > amax的弧(t, s),则从在这个改造后的图中一定没有无源汇的可行流:否则将这个可行流中的弧(t, s)除去,就得到了原图中s到t的流量为a'的流,大于最大流量amax,产生矛盾.
可以二分枚举这个参数a,即下界b(t, s),每次用问题[1]判断是否有可行流.这样就可以求出最大流.
同理,问题[4]要求最小流,只要二分枚举上界c(t, s)即可.
因为朴素的预流推进算法O(N3),总复杂度为O(N3 log2流量) .
思路:
无源汇 (附加源汇+最大解决)
有源汇 (附加(T,S)->无源汇)
习题:SGU194 Reactor Cooling
SGU176 Flow Construction
参考文献:
[1]安徽 周源,《一种简易的方法求解流量有上下界的网络中网络流问题》,IOI2004国家集训队作业
[2]江涛,《最大流在信息学竞赛中应用的一个模型》,NOI2006冬令营
最小费用流 Minimum cost flow
对于有向带权图G=(V,E,C,W),求一个图上的流f,使得每条边的流量与费用的乘积加起来的总和最小,且总流量等于d.下面是最小费用流问题的数学模型的表述:
最小费用最大流问题:总流量d为网络的最大流的最小费用流问题.
找最小费用路 Finding minimum cost path
每次在残量网络中找最小费用路并沿着它增广,直到不存这样增广路.
算法:
用Bellman-Ford在残量网络中求s-t的最小费用路,若不存在,结束;否则转2.
沿着找到的最小费用路改进残量网络.转2.
设v是最大流量,则算法最多迭代v次,故复杂度为.
习题:FJOI 2002 蚯蚓问题
找负权圈 Finding negative circle
在最大流的残量网络中不断的找负费用圈并沿着它增广,直到不存这样的负圈.易知,每次沿负费用圈增广,总费用总是不断的减小.
算法:
用最大流算法求出网络的任一个最大流的残量网络.
用Bellman-Ford算法找残量网络的负费用圈,若不存在,结束;否则转3.
沿着找到的负费用圈改进残量网络.转2.
设c为容量最大值,w为费用最大值.因为每次消圈,费用至少少1,而初始费用不超过mcw,所以复杂度上限:,是伪多项式算法.但实际上,会比这个快多了.还有一个按照特定次序消圈的算法,.所以最小费用流问题是P类的.
习题:Ural 1237 Evacuation Plan
网络单纯形 Network simplex algorithm
我不会阿!!!
匹配 Matching
所有的匹配算法都基于增广轨定理:一个匹配是最大匹配当且仅当没有增广轨.这个定理适用于任意图.
Kuhn-Munkres
Edmonds
Gabow
二分图 Bipartite Graph
由于二分图(又称二部图)的特殊性,使得它可以转化成流问题来解决.
习题:Ural 1203 Conference (最小点覆盖)
无权图-匈牙利算法 Unweighted - Hopcroft and Karp algorithm
匈牙利算法,匈牙利数学家Edmonds于1965年提出.
带权图-KM算法 Weighted –Kuhn-Munkres(KM) algorithm
构造可行顶标:结点函数l,对任意弧满足:.
引入相等子图:G的生成子图,包含所有点,但只包含满足的所有弧.
下证相等子图的一个性质定理:
如果相等子图有完美匹配,则该匹配是原图的最大权匹配.
证明:设M*是相等子图的完美匹配,M是原图的任意完美匹配.
(1)是根据相等子图定义;(2)是根据可行顶标定义.
所以关键是寻找好的可行顶标,使相等子图有完美匹配.
算法思想:随便构造一个可行顶标(例如Y结点顶标为0,X结点的顶标为它出发所有弧的最大权值,然后求相等子图的最大匹配)
-若存在完美匹配,算法终止
-否则修改顶标使得相等子图的边变多,有更大机会存在完美匹配
Kuhn和Munkras
一般图General Graph
无权图-带花树算法 Unweighted - Blossom (Edmonds)
朱(永津)-刘(振宏)算法(1965)
Edmons算法(1968)
Dictionary of Algorithms and Data Structures NIST
Wikipedia
Introduction to Algorithm
[ADN.cn][library]summary 图论总结 2006-2-9
/31
3
3,4
3,7
2,6
t
s
2
1
3
2
x
y
3
3
指针
权值
终点
起点
2
1
4
4
t
s
2
1
+∞
3
3
2
1
4
5
6
8
7
3
2
1
5
4
3
2
1
0
7
4
6
3
0
3
5
0
3
0
4
2
0
6
4
0
9
3
8
2
5
4
3
4
2
1
4
t
s
2
1
3
2
x
y
3
3
2
1
4
+∞
+∞
3,4
3,7
2,6
t
s
2
编号
1
2
3
4
5
6
7
8
起点
1
1
2
3
4
4
5
5
终点
2
3
4
2
3
5
3
4
权值
8
9
6
4
0
3
6
7
作为起点的点
0
1
2
3
4
5
最后边的编号
0
2
3
4
6
8
编号
0
1
2
3
4
5
6
7
8
起点
nil
5
3
4
1
2
1
4
5
终点
nil
4
2
5
2
4
3
3
3
权值
nil
7
4
3
8
6
9
0
6
前趋
nil
0
0
0
0
0
4
3
1
作为起点的点
1
2
3
4
5
最后边的编号
6
5
2
7
8
+∞
3,4
3,7
2,6
tT
s
2
1
4
t
s
3
3
3
2
1
4
4
t
s
2
1
+∞
1
2
1
+∞