720 likes | 901 Views
图论常见模型与思想. 何亮 roba269@gmail.com. 强连通分量相关. 概念:有向图的强连通分量 (SCC) 是指,对于强连通分量里面的任意两个点 u,v ,都存在从 u 到 v 的路和从 v 到 u 的路 算法:复杂度均为 O(V+E) Kosaraju ( 两次 dfs) Tarjan / Gabow ( 一次 dfs). Tarjan. 对图进行 DFS ,每个 SCC 都是 DFS 树的一个子树。在搜索时用堆栈维护当前正在处理的结点,栈顶的若干元素即组成一个 SCC 。 类似求割点的过程,定义 Low[u] = min(dfn[u],
E N D
图论常见模型与思想 何亮 roba269@gmail.com
强连通分量相关 • 概念:有向图的强连通分量(SCC)是指,对于强连通分量里面的任意两个点u,v,都存在从u到v的路和从v到u的路 • 算法:复杂度均为O(V+E) • Kosaraju (两次dfs) • Tarjan / Gabow (一次dfs)
Tarjan • 对图进行DFS,每个SCC都是DFS树的一个子树。在搜索时用堆栈维护当前正在处理的结点,栈顶的若干元素即组成一个SCC。 • 类似求割点的过程,定义 Low[u] = min(dfn[u], low[v], {(u,v)为树边} dfn[v], {(u,v)为后向边} ) • 若对某点u有 dfn[u] = low[u],说明以u为根的子树上的点为一个SCC
tarjan(u) { DFN[u]=Low[u]=++Index // 为u设定dfn和Low初值 Stack.push(u) // 将节点u压入栈中 for each (u, v) in E // 枚举每一条边 if (v is not visted) // 如果节点v未被访问过(树边) tarjan(v) // 继续向下找 Low[u] = min(Low[u], Low[v]) else if (v in S) // 如果节点u还在栈内(后向边) Low[u] = min(Low[u], DFN[v]) if (DFN[u] == Low[u]) // 节点u是SCC的根 repeat v = S.pop // 将v退栈,为该SCC中一个顶点 print v until (u== v) }
强连通分量相关 • 关键点: • 一个强连通分量内部的所有点,在某种意义上是“等价”的。 • 图中的边存在某种意义上的“传递性”。 • 通过缩点操作可以把复杂的一般有向图转化为DAG,使得问题简化
例题分析 • Popular Cows (USACO Fall 03) • POJ 2186 • N头奶牛,给出若干个欢迎关系A B,表示A欢迎B,欢迎关系是单向的,但是是可以传递的。另外每个奶牛都是欢迎他自己的。求出被所有的奶牛欢迎的奶牛的数目。 • 奶牛数目N≤10000 • 直接的欢迎关系数目M≤50000
例题分析 • 如果A欢迎B,就连一条从A到B的有向边 • 容易发现,在同一个强连通分量里的点具有同样的“受欢迎程度”:能够到达它们的点集是相同的,从它们出发能够到达的点集也是相同的。 • 我们求出原图的强连通分量,然后收缩……
例题分析 • 容易发现,新图中唯一的出度为0的点即为所求。 • 因为新图不含有环,这样的点一定存在。 • 如果出度为0的点不唯一则无解。 • 时间复杂度 O(E)
例题分析 • WTommy’s Trouble(TOJ2233/TOI 1135) • WTommy需要向所有人通知某件事情,因为人数众多,他想出了一个省力的方法:他只通知队中的某些人,然后让这些人去通知所有他们认识的人,这些新被通知的人又去通知更多的人……直到最后队中的所有人都被通知到。 • 给定最初时WTommy通知每个人所需的花费,现在他想求出一种方案,使得花费最少,并且保证最终所有人都能被通知到。
例题分析 Input 4 3 30 20 10 40 1 2 2 1 2 3 Output : 60 1 ≤ N ≤ 10000, 0 ≤ M ≤ 200000
例题分析 • 同一个强连通分量里,只要有一人被通知即可 • 缩点后得到的DAG中,如果一个点被通知,则它的所有后继结点都会被通知。故只需通知入度为0的点 • 在入度为0的每个点所表示的连通分量中,通知花费最少的那个人,即为最优解 • O(E)
例题分析 • NOIP 2009 最优贸易(Trade) • C 国有 n 个大城市和 m 条道路(单向或双向),每条道路连接这 n 个城市中的某两个城市。水晶球在各地有不同的价格。某商人准备从1走到n(任何城市可以经过多次),在某个城市买入,并在另一城市卖出,收益即为价格之差。他最多只买入和卖出1次,求最大收益。
例题分析 • 如下图,五城市水晶球价格分别为 4,3,5,6,1 。则最高的方案是14545。在第一次到5时买入,第二次到4时卖出,收益为6 – 1 = 5
例题分析 • 若图中无环,则可以DP求解: • 设v[i]表示i点的物品价格。令dp[i]表示从i到N的路径中的最高价格。若从i点买入,则收益为dp[i]-v[i]。最终结果即为max(dp[i]-v[i]) • 状态转移方程: • dp[i] = max(v[i], max{dp[j], 当ij有边时}) • 注意:应排除不能到达N的点
例题分析 • 若图中有环…… • 在同一SCC里的全部点的“连通性”是等价的:能够到达它们的点集是相同的,从它们出发能够到达的点集也是相同的。 • 若从此SCC买入,则一定买价格最低的点 • 若从此SCC卖出,则一定买价格最高的点
例题分析 • 最终解法: • 对原图求SCC并缩点,设新点i中最高价格点为H[i],最低价格点为L[i]。在新的DAG图上有DP: • dp[i] = max(H[i], max{dp[j], 当ij有边时}) • 最终结果为max{dp[i] – L[i]} • 注意:应排除不能到达N的点
例题分析 • Poly-time Reductions(Hefei 2008) • 给定一个有向图G,求一个包含最少边的有向图G’,使G和G’的传递闭包相同。 • 图的传递闭包是指,若存在边AB, BC,则必存在边AC • N <= 100, M <= 10000
Input 3 3 1 2 2 3 1 3 Output 2 Input 4 6 1 2 2 1 2 3 3 2 3 4 4 3 Output 4 例题分析
例题分析 • 求强连通分量,缩点…… • 在同一强连通分量内部,最少需要几条边? • 不同分量之间的边,有哪一种是不必要的?
例题分析 • 先求传递闭包 • 对于边(u,v),若存在一点k,使得uk且kv,则边(u,v)是不必要的 • 易得一个O(n^3)的算法 • 证明?
路径覆盖相关 • 经典模型:给定一有向无环图,要求用最少的不相交路径把所有点覆盖上 • 解法:把原图中的每个点i拆为两个,分别属于X集和Y集。对于原图中的有向边(i,j),在新图中添加边(Xi, Yj),得到一个二分图。最小路径覆盖数 = 原图顶点数 –新图最大匹配数 • “拆点”思路广泛应用于此类问题
路径覆盖相关 • 简单解释: • 原图的路径覆盖和新图的匹配间有对应关系:每条覆盖边都是匹配中的一条边,且只有路径的最后一个点没有被匹配上。 • 路径要求不能相交,恰好对应于匹配中两匹配边不能有公共端点。 • 于是求最大匹配后,不能被匹配上的点,即是路径的最后一个点。有多少个不能被匹配的点,就有多少条路径存在。路径数=原点数-匹配边数。因此我们使匹配边数最大,即是使路径数最小。
例题分析 • Hanoi Tower Troubles Again! (OIBH Contest) • ZOJ 1239 • 题目大意:给定柱子数N,按编号从小到大放球,要求:如果该球不在最底数,则该球和它下面一个球的编号之和必须为完全平方数。 • 问对于给定的N,最多能放多少球上去。 • N<=50
例题分析 • 考虑一下相关的问题: • 给k个球,问最少需要多少个柱子才能把它们都放上? • 如果能解出上述问题,则二分k值即可求解原问题。 • 继续类比……球→??, 柱子→??
例题分析 • 如果a+b是完全平方数(a<b),那么我们连一条有向边(a,b)…… • 于是,问题变成了求DAG的最小路径覆盖。 • 因为连边时保证a<b,所以无环 • 路径→柱子 • 路径不相交→同一个球不能用两次 • ……
例题分析 • POJ Monthly / POJ 3216 • 题目大意:城市有Q个城区,有些城区之间有路连接,经过这些路所需时间已知。现在有M个维修任务要进行,已知每个任务的地点、deadline和完成每个任务所需时间。维修工可以从任何一个城区开始,完成任务后可以到另一个城区继续。问至少要派出多少个维修工才能及时任务。(Q<=20, M<=200)
Sample Input 1 2 0 1 1 10 1 5 10 Sample Output 2 例题分析
例题分析 • Floyd预处理所有点对间最短路径dis[][] • 设有任务a,b,如果在完成任务a后还来得及走到b处继续,即deadline[a] + cost + dis[a][b] <= deadline[b],则连一条有向边(a,b)…
例题分析 • 由建图的过程知,这个有向图中一定不会出现环…… • 于是问题转化为DAG的最小路径覆盖 • 经典问题,(点数-最大匹配数)即为最终结果。
Dilworth定理 • NOIP 1999 导弹拦截 • 导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。 • 给定依次飞来的导弹高度,问(1)一套系统最多拦截多少导弹 (2)拦截所有导弹最少需要几套系统
Dilworth定理 • 第一问是简单的最长不上升子序列O(nlogn) • 第二问 • 解法一:最小路径覆盖 (复杂度过高) • 解法二:……贪心?
Dilworth定理 • 偏序关系:定义在集合X上的二元关系≤,对X中任意元素a,b,c满足三条性质: • 1. 自反性:a≤a • 2. 反对称性:若a≤b且b≤a,则a=b • 3. 传递性:若a≤b且b≤c,则a≤c • 对于X中任意两元素a,b,若有a≤b或b≤a,则称a和b是可比的,否则为不可比。
Dilworth定理 • 一个链C是X的一个子集,它的任意两个元素都可比。 • 一个反链A是X的一个子集,它的任意两个元素都不能进行比较。 • Dilworth定理: 最大反链的大小 = 最少可划分成的链的数目
Dilworth定理 • 若在拦截导弹a以后还能拦截导弹b,则认为存在关系a≤b(易得此为偏序关系) • 问题一:求最大链 • 问题二:求最少划分成多少个链。由Dilworth定理,等价于求最大的反链 • 在此处,最大的反链,即最长上升子序列 • O(nlogn)
Dilworth定理 • 思考: • 能用dilworth定理解决的问题一定能用路径覆盖解决吗? • 反之是否成立?什么情况下只能用匹配来做?
Dilworth定理 • HDU 3335 Divisibility • 给定n个数(n<=1000),要求从中选出一些数,满足条件:若选择了a,就不能选择任何a的约数和倍数。问最多能选出多少数 • 例如有三个数1,2,3,最多可以选出两个: 2,3
Dilworth定理 • (a是b的倍数)这是一个偏序关系,则此题要求的即为最大反链的大小 • 此题中反链难以直接计算,利用Dilworth定理,等价于计算最少可划分为的链数 • 于是我们回到最小路径覆盖,用二分匹配求解即可
例题分析 • TJOI 2009 细菌培养 • 生物实验室的培养皿中有N只细菌,每只细菌i有三个属性值Ai,Bi,Ci,若细菌i和j发生接触,并且细菌i的三项属性值都大于或等于细菌j时,i就可以把j吞噬掉。由于某些神秘的原因,每只细菌最多只能吞噬K只细菌。问培养皿中最少会剩下多少只细菌?
Input: 3 1 10 20 30 10 20 30 10 20 30 Output: 1 Input 4 2 100 100 100 50 50 50 40 50 60 10 100 200 Output 2 例题分析
广义的路径覆盖 • 不考虑三个属性完全相等的情况,如果当i可以吃掉j时连有向边ij,那么可以得到一个DAG • 若K=1,则此问题即为DAG的最小路径覆盖 • 若K>1 ?
广义的路径覆盖 • 类比K=1的情况,不同之处在于,每个左边的点可以匹配多个右边的点,于是—— • 把每个点i拆成两个点i和i’ • 若i能吃掉j,连边(ij’),容量为1 • 从源点到每个左侧点i连边,容量为K • 从每个右侧点i’到汇点连边,容量为1 • 求最大流F,则n-F即为所求
广义的路径覆盖 • 对于属性完全相同的细菌,因为是完全等价,我们可以任意设定一个顺序,例如,以在输入数据中出现的先后顺序为序,只允许排前面的细菌吃掉排后面的细菌。
SPOJ TOURS • 有N个城市M条单向道路,道路有长度权值。要求设计出若干条环线,使得每个城市都属于(且仅属于)一条环线。每条环线最少包含两个城市,且经过每个城市最多一次。要求所有环线的总长度之和最小。N <= 200
Input: 5 8 1 2 4 2 1 7 1 3 10 3 2 10 3 4 10 4 5 10 5 3 10 5 4 3 Output: 40 两条环线: 1 – 3 – 2 – 1 5 – 4 – 5 SPOJ TOURS
广义的路径覆盖 • 思考: • 环覆盖? • 与路径覆盖有何区别与联系?可否借用类似的思路?