图论
约定
树的性质
Example1([HDU6035]Colorful Tree)
考虑每种颜色的贡献,一种颜色的贡献显然是删去所有这个颜色的边后,剩下的联通块之间的路径.
Example2([2022qbxt国庆Day1]tree)
首先考虑分开处理每个点,在做每个点的时候假设它的所有子节点全部已经满足条件了,最终我们再通过计算组合数的方式计算即可.
那么最后,我们需要对于每个点进行处理,假设我们已知这个子树的集合是
其实也就是个二项式反演的形式.
这题还需要一些技巧优化,我们首先发现由于
Example3(CF1628E Groceries in Meteor Town)
因为要求路径最大值,所以先建Kruskal重构树.然后问题转化为求一个点和一群白点的LCA是谁.
树上多点LCA有个经典性质:也就相当于其中
至于区间覆盖可以用线段树.
Example4(loj3692)
注意到
我们考虑处理邻域乘,设
然后询问的时候直接暴力跳
同样的思路可以脱离点分治处理很多邻域问题.
树的直径
-
定义:树中最长的一条简单路径.
-
树的直径可能有多个.
-
直径的两个端点一定是两个叶子节点.
-
如果树有多条直径,树的不同的直径的中点/中边一定是相同的.
-
到一个点距离最远的点一定是直径的一个端点.
-
对于两棵树,如果第一棵树直径两端点为
,第二棵树直径两端点为 ,用一条边将两棵树连接,那么新树的直径一定是 中的两个点.
上述的证明大都是考虑反证法:如果不成立,则一定存在一条更长的直径.
Example1([SDOI2013]直径)
有一个做法是:考虑找到直径的中点/中边,找到它到两边的最远距离的点,显然两边的点分别的以中点/中边的两个端点为根的LCA中间的部分就是一定会被包含的边.
树的重心
-
定义:树的重心是删去后所有剩余子树大小最大值最小的点.
-
树的重心是删去后所有剩余子树大小全部小于等于
的点. -
树的重心只有可能有一个或两个.
-
如果树有两个重心,那么这两个重心相邻.
-
树的重心是所有点到其距离之和最小的点.
-
把一个树添加或删除一个叶子,那么它的重心最多只移动一条边的距离.
-
把两个树通过一条边相连得到一个新的树,那么新的树的重心在连接原来两个树的重心的路径上.
(2)的证明如下:
如果重心是
另外,如果一个点删去后所有剩余子树大小全部小于等于
(3)(4)的证明如下:
首先证明:如果有两个点都是重心,那它们一定相邻.
考虑如果二者不相邻,那删去它们后剩下的最大子树大小一定相等,设这两个点分别为
而树上不可能有超过两个点两两相邻,于是最多只有两个重心,且它们一定相邻.
(5)的证明如下:
考虑如果
由于调整是一步一步做的,显然只需要判断所有和
(6)的证明如下:
首先,如果加入一个叶子节点后,各个子树大小仍然都
不然,显然是往叶子节点移动一格或者加入一个相邻的重心.
(7)的证明如下:
不妨设两棵树大小分别为
对于
Example1([CSP-S2019]树的重心)
首先取重心
接下来我们考虑对于每个点
整理得到:
考虑这个怎么计算:如果没有删边必须在
接下来我们需要考虑
考虑
树的结构的维护
Example1
给定一棵树,树上点有点权
首先注意到为了保证
如果我们能一开始处理出根的所有儿子的
所以考虑不断向上合并信息.不难发现此时一个点要处理出多对
但是,我们还需要保证不能跳着选点.也就是说我们要保证选中一个点,这个点的父亲必须选,怎么办呢?
一个方式是,我们把排序方法从只看
另一个方式是,我们每次直接把当前子树根节点扔到堆顶.但是需要满足堆的性质.不难发现如果这个点
dfs树的性质
Example1([CF1361E]James and the Chase)
如何判断一个点是否是好的呢?首先,如果要求是任意路径,那一个点是好的当且仅当它是一个叶向有根树的根.
现在要求是简单路径,那也就是说如果走了重复点是可以忽略的,这也就是说这个叶向有根树可以有反走边,而显然不能有横插边.不难发现这是充要条件.
另一个问题是:如何快速判断一个点是否满足上述条件呢?首先我们求出以一个好的点为根的dfs树(随机选取一定数量的点,如果一个都不是好点直接输出
这是为啥呢?首先,因为我们是以一个好点为根跑的dfs树,所以
Example2(Loj 6276)
找到所有颜色相同的点对
圆方树的性质
-
对于任意的非空无向图
,一定存在一个 的点双连通分量 ,使得 中只有不超过 个节点是 的割点.其中,若 中没有 的割点,则有 . -
若一个点双连通分量不为
,则该点双连通分量中至少有一个简单环. -
在仙人掌上的每个点双连通分量要么是
,要么是一个简单环. -
对于一个不是
的点双连通分量中的任意一个点 ,一定存在一个简单环 使得 在 上. -
对于一个不是
的点双连通分量中的任意两个点 ,一定存在一个简单环 使得 在 上. -
对于一个不是
的点双,任给一点 和一边 ,一定存在经过 的简单环. -
对于一个不是
的点双,任给两点 和一边 ,一定存在一条 的简单路径.
(6)的证明非常变魔术,你考虑把
(7)考虑(6)就行,先找到
任意图的性质
- 若一张无向连通图
中存在 个不同的一度点 ,则一定存在一个点 使得存在 条两两没有公共边的简单路径满足其中一个端点均为 且另一个端点分别为 .(证明考虑求生成树后讨论LCA)
dsu on tree
Example(QOJ5020)
我们考虑树链剖分,这样将问题转化为三部分:
-
对于某个点而言,到它距离
的点数量.这个问题可以使用点分治解决. -
对于某条重链的上半部分而言,它连接的所有轻子树中,到它距离
的点数量.这个问题直接dsu on tree. -
对于某个点而言,在它子树内到它距离
的点数量.这个问题也可以直接dsu on tree.
为什么转化为三个部分就能求解呢?我们考虑一条链
现在的问题在于怎么求(2)和(3),先考虑(2),我们对于每一条重链从顶端走到低端不断地加入轻儿子,然后维护BIT就行.(3)是类似的,只不过是需要从底端走到顶端.
注意如果把重儿子和轻儿子分开处理,那么可能会在一些奇怪的地方算重,解决方法是特判
最小生成树
Example1(CF1550F Jumping Around)
首先考虑离线.注意到每次肯定跳到一个自己能跳到的点,而这个点应该是所需灵活度最小的点.
考虑boruvka算法,建立最小生成树并判断.
Kruskal重构树
最小生成树时,每一次加边的时候把那个边变成虚点,两个点连到这条边上.任意两个点的LCA就是它们路径上的最小边权.
最短路
Example1(CF1753D The Beach)
首先,自然的想法是把格子图黑白染色.
然后,我们注意到一个床是不可能被移动两次及以上的.因为如果是横着动两次,那不动自然就有一对空位置了;如果是转两次,考虑转的目的一定是为了空出某个位置或某两个位置(不可能为了空出三个位置,显然这么做很闲),一次操作足矣;如果是动一次转一次也是一样的,要么转的很闲要么原本就存在这么一对空位置.
我们再进行一步转化,考虑把动床改为动格子.换句话说,每个格子可以通过一定的代价移动到和它相邻的床的与它不相邻的那个位置上.注意到移动格子的过程只会把黑格子移动到黑格子,白格子移动到白格子.
于是建立超级源点跑两边最短路,枚举最后床放在哪里即可.不过这里有一点是一个床有没有可能被黑白最短路同时跑了一遍,是有可能的,但这么跑一定不优秀,不可能是最小答案.
Example2([CF843D]Dynamic Shortest Path)
注意到
但是怎么跑呢?注意到维护每个点最短路的增量,并且在路径的增量上跑01bfs,自然可求.
Example3 同余最短路([luoguP2371]墨墨的等式)
因为
设
那么怎么求
这显然是一个最短路问题.
差分约束
Example1([AGC056C] 01 Balanced)
将
然后另一个问题在于这玩意为啥不会让
2-SAT
Example1(CF1697F)
对每个点建立
Example2(2021集训队互测 序列)
注意到如果
而且一定可以刻画所有的条件.
对偶图
Example1([CSP-S 2021] 交通规划)
先考虑如果附加点的颜色全都相同,那肯定输出
考虑附加点的数量为
而如果附加点的数量很多怎么做呢?稍微思考一下
广义串并联图/三度化
定义
定义:不存在
删一度点
经典问题引入:树上带权最大独立集.
首先dp是可以实现的,我们考虑是否存在贪心算法.
首先,如果不带权,我们显然可以每次选取一度点或零度点,并删去所有相连的点.这样做显然是最优的.
但怎么做带权的方法呢?我们注意到可以先删掉所有负点权的点,然后可以加入剩下的所有零度点.
那么对于一度点呢?对于一个一度点
我们把类似这样的操作称为删一度点.
缩二度点
问题引入:给定一个仙人掌,每个点可以染色为
首先如果有一度点和零度点,我们仍然可以使用删一度点的操作.
如果没有,考虑仙人掌上的一个点双一定是一个简单环.而且一定存在一个点双
那么对于这个点双上的一个非割点
冷静思考一下,我们想办法把
叠合重边
注意到使用缩二度点的时候,会把一个三元环缩成两个点及链接它们的两条重边,但是我们可以直接把重边合起来,我们把类似这样的操作称为叠合重边.
正确性证明
接下来我们证明:任何广义串并联图都可以通过以上三种操作缩为一个点.
引理1
对于一个无向图
考虑用逆操作还原原图.删一度点的逆操作是加入一个点,叠合重边的逆操作是将一条边变成两条边,这两个操作显然不会使一个不是广义串并联图的图变成广义串并联图.接下来考虑缩二度点的逆操作:删掉一条边
由于这个图不是广义串并联图,所以一定存在一组反例点
于是引理得证.
引理2
任意一张所有点的度数都大于等于
这个引理的严格证明有些麻烦.我们冷静一下,一个四个点的完全图满足以上条件且不是广义串并联图.而其他的图感性理解一下应该可以通过缩路径的方式变成一个四个点的完全图.
结合引理1,我们得知任意一个操作后不能变成单个节点的图的无向连通图不是广义串并联图.
引理3
任意一个满足
考虑缩完点后,所有点的度数
Example1(22zr提高十连测day6摆件)
首先考虑颜色之间没啥区别,所以对于一棵树来说,朴素的dp是可以的.
简单来说,设
接下来考虑先随便找一棵生成树,然后暴力枚举多余的反走边的深度较低的叶子节点的颜色,再进行dp即可.
另外也可以缩点后做,不过对于这题没啥区别.
Example2([JOI Open 2022] 放学路)
广义串并联图的一个很重要的思想是:我们通过一些手段改变这个图的形态为一个好做的形态,但是答案又和原图相同.
在这个思想的指导下,我们考虑这个题能否进行三度化.不过注意起点和终点简单特判一下,别把他们给删了.这样我们最后如果得到了一个只有起点和终点的图,那就一定是no.
然后如果没有只得到起点和终点呢?对最短路图建DAG,考虑如果
如何保证
点分治
Example1(CFgym101002K)
点分治,假设当前分治重心是
点分树的性质
-
点分树的高度是
级别. -
两个点在原树上的路径一定经过其在点分树上的LCA.
Example1(codechef [BTREE])
这题用到了一个经典套路:一个树形连通图的点数减去边数为
Example2
给定一棵树,现在在上面选定
考虑如果确定了
那么怎么优化呢?我们注意到如果以一个点
具体来说,我们建立点分树,然后从点分树的根开始枚举带权重心,如果当前没有一棵子树选了
边分治
需要建立虚点转二叉树.
边分树的性质
-
非叶子节点代表边,叶子节点代表点.
-
边分树的高度是
级别. -
边分树上每棵子树中的叶子节点一定联通.
-
是一棵完全二叉树.
-
两个点在原树上的路径一定经过其在边分树上的LCA所代表的边.
二分图
定理
最大流-最小割定理
Hall定理
对于二分图
必要性很显然,接下来说明充分性.设
显然
另外,Hall定理有一个推论:正则二分图一定存在完美匹配.什么叫正则二分图,就是所有的点的度数(不为
Vizing定理
设
设
对于一般图,我们有:
考虑这个的证明:我们每次将一对点
二分图最大权匹配
假定二分图两边两两有边(不是的话可以补上
我们给每个点一个顶标权值
如果我们规定了一组顶标后,取出所有满足
这是为啥呢?考虑此时的最大权其实也就是
那么我们该怎么得到一个相等子图呢?考虑先构造一组合法的顶标,让左部端点取边的最大值,右部端点取
从左侧任意一个非匹配点出发,在相等子图上走增广路并增广.如果增广失败,我们将访问过的左部端点全部减去
使用bfs优化,可以发现只会扩大
Example
Example1([ XVII Open Cup named after E.V. Pankratiev. Grand Prix of Japan(openstrain contest 1489) B]Point Pairs)
看到这种要求横坐标或纵坐标相同的题,有一个自然的想法是建立二分图,对于点
首先发现的是,二分图不同的连通块可以分开处理,我们接下来只讨论一个连通块的情况.如果这个连通块有奇数条边,显然一定不行.而又可以发现,如果这个连通块有一个点度数仅为
然后我们可以使用可撤销的分治解决这个问题.
网络流常见模型
最大流
最小费用最大流
最小割
最大流
最小割求方案。这个是简单的,我们删去所有流量
Example1(luoguP4313 文理分科)
先把所有的满意值全部吃下,然后考虑放弃哪些.
对于每个人
然后再对每个点建立一个虚点
从这也可以看出来,大部分最小割的题目其实就是将冲突的选项放到一条路径中,然后考虑放弃哪些,将这个限制用最小割表示出来.
Example2([HNOI2013]切糕)
也是显然的最小割,唯一难处理的地方在于相差
这个怎么做呢?建图后先每一竖轴都变成了一条链,我们在链之间加一些
这题同样告诉我们:对于最小割题目中的限制条件,几乎都是需要考虑破坏最小割结构的(也有可能是用费用流限制).
Example3(uoj704)
二分图最小割计数.
先求出最小割,然后显然每个匹配的三条边一定会选择一条割掉.
不妨设
考虑每个非匹配边
-
在最大匹配 中, 不在.则 . -
在最大匹配 中, 不在,则 . -
在最大匹配 中, 在最大匹配 中,则 或 .
前两种是好处理的,考虑第三种:显然所有都选
不妨折半搜索,按照拓扑排序,确定前一半哪些是
接下来只需要判断哪些位置可以选
二分图匹配
二分图最小点覆盖
二分图最小点覆盖
问题在于如何求解方案.
我们从左侧的非匹配点开始dfs,走还有残留流量的路径.并将路径上所有的点全都打上标记.那么左侧所有的未标记点和右侧所有的标记点就是一组合法的方案.
这是为啥呢?首先我们注意到,左侧的非匹配点一定会被标记,右侧的非匹配点一定不会被标记.
为啥右侧的非匹配点一定不会被标记呢?因为如果被标记了,从左侧非匹配点到右侧非匹配点这条路径的起始边和终边就都是非匹配边,显然是一条增广路.
然后我们又注意到:对于一组匹配点,要么两者都被标记,要么两者都不被标记,因为一旦走到了右侧点,下一步必然走向左侧点.而如果走到了左侧点,也必然是从右侧点走过来的.
接下来我们讨论一下:
对于非匹配边,由于其必然连了一个左侧非匹配点,所以它的右边必然被选择了.
对于匹配边,不难发现它会被某个匹配点覆盖掉.
于是得证.
当然,上面的证明略显啰嗦.事实上我们这么考虑:
首先,我们按照套路,求出
然后我们取所有不在这个点集的左侧点和所有在这个点集的右侧点,这样所有的点被分为了四个部分,边也自然被分为了四个部分,讨论一下就知道这四个部分中有一个部分是不存在边的.于是得证.
二分图最大独立集
二分图最大独立集
Example1(CF1404E)
在两个可选矩形的边界处建立一个点,如果它被选了,那么说明这个矩形和上面那个矩形被一起覆盖了.然后注意到每有一个点被选,自然就多覆盖了一个矩形,显然一个矩形不可能又跟纵向的一起被覆盖又跟横向的一起被覆盖,在他俩之间连边跑最大独立集即可.
感觉还是类似于最小路径覆盖,将这种两个一起被覆盖就减少答案的东西转换成一整条流.
最大权闭合子图
原图的边流量设为
Example1(luoguP4177)
只需要把中间的
最小路径覆盖(覆盖点)
将每个点
还有一个版本是可以重复走点,做一遍传递闭包就行.因为可重复相当于原图上的可跳点,这个版本又叫最小链覆盖.
Example1([网络流24题]魔术球问题)
枚举球数,不断在残联网络上加边并在新图跑最小路径覆盖即可.
最长反链
反链是一个点的集合,满足这个集合中的点两两不可达.
最长反链
为啥呢?因为发现做完传递闭包后等价于新图的最大独立集.当然图是有性质的,观察一下可重复走点的最小点覆盖就可以发现等价于传递闭包后在二分图上求最大独立集.
Example1([CF1630F]Making It Bipartite)
首先显然的一点是,对于任意一个数字
那么我们该怎么办呢?如果是只能出现
平面图最小割
平面图最小割
最小费用任意流
一般费用流,但是当当前增广路代价为正的就停止增广.
和最小费用最大流不一样,这玩意是可以增量的.
只需要考虑所有新的从源到汇的增广路以及增加过程出现的负环即可.
Example1(luoguP4694 [PA2013]Raper)
费用流模型很好建立,问题在于这个东西好像跑费用流有点慢.
那咋办呢?我们考虑到费用流是有凸性的.所以搭配一下wqs二分.
然后分一下三种情况讨论:
-
直接
的负增广路,相当于选取最小的 和当前的 搭配. -
有一条
的负环,相当于以当前的 代替前面的某个较大的 . -
有一条
的负环,注意到这个环必然没意义,因为不可能存在一条 的负路径(不然反路径就是正的,而最小费用任意流不可能流正路径),所以这种情况不如直接选 的路径.
讨论完拿堆模拟一下就行.
这引出了著名的模拟费用流算法.
负费用最小流
一般费用流,但是当增广当前增广路时费用变成正的就停止增广.
注意如果两条增广路代价相同选流量大的那条.
有负环的费用流
首先注意到:如果初始图没有负环,那无论后面怎么流都不可能出来负环.因为这意味着要么是一开始流了个正环,要么是一开始有负路径不走走正路径,都不太可能.
对于所有的负边
为啥会这样呢?
首先先证明正确性,这个东西相当于一开始跑了一下
好,那么为啥这么做就不会出现负环了呢?因为你不可能在跑
另外有一点是,一个点可能向
模拟费用流
对于特殊的图,模拟EK费用流的增广过程并进行操作.
对着例题记吧.
Example1(luoguP4694 [PA2013]Raper)
散题
Example1([CQOI2014]危桥)
有一个朴素的想法是:我们直接按题意建图,然后
问题在于,这样有可能会出现
做法是,我们交换
为什么呢?我们注意到此时网络上的流量分为四种:
在第二次跑网络流时,我们不妨直接将
图的计数问题
Prufer序列
我们可以将一颗有编号
首先证明一个树可以对应到一个序列:每次选择一个度数为
然后证明一个序列可以还原成一棵树:
我们可以通过序列得知每个点的度数,每次找到度数中最小的那个点并把它与序列中的第一个元素连边并删去序列中的第一个元素,不断这么做显然可以还原树.
Example
一个
令
那我们所需要做的也就是枚举每个连通块所新连出的边数
注意到我们有多项式定理:
于是原式
Prufer序列的矩阵树定理理解
事实上,Prufer序列其实是可以拿矩阵树定理代替的(但是更麻烦一点).
我们先考虑证明Cayley公式:构造矩阵:
其主余子式为:
将所有行全部加到第一行:
全部加下来,然后就成了上三角矩阵,将对角线乘起来就是
连通块的结论是类似的.
LGV引理
设
记边
记
设矩阵
证明:
根据行列式的定义,我们有:
考虑后面那部分,
接下来只需证明
设所有
-
. -
. -
. -
.
上面的结论即得证.
我们不妨考虑
Example
现在有
路径不相交,则终点排列只有可能是
矩阵树定理
无向图情况
定义无向图的度数矩阵
令
定义无向图的基尔霍夫矩阵(又称拉普拉斯矩阵)
记
引理:无向图的基尔霍夫矩阵的任意一个代数余子式都相等.
证明:考虑删去第
接下来,用
定义
注意到:
当
定义
接下来我们需要证明:如果
如果集合没有构成一个生成树,则至少存在一个简单环.如果有某个点是孤立点那么答案肯定是
考虑这种情况下,如果有两条边
所以定理得证.
Example([省选联考 2020 A 卷]作业题)
给定一个图,设第
首先前面的
不妨进行扩域,令
另外,注意到这样做复杂度
Example([北京省选集训2019]生成树计数)
给定一个图,设第
考虑将第
有向图情况
定义有向图的出度矩阵
令
定义有向图的出度基尔霍夫矩阵
记
设
下面只简单提到根向生成树的证明,叶向同理.
类似于无向图,我们考虑构造
剩下的部分与无向图类似.
BEST定理
设
其中
考虑如果勒令以
但是如果没有规定起点,考虑循环重构,在我们选择不同的边当作初始边时,只需循环一下总体的顺序,就可以得到以另一条边为初始边的另一个图,所以答案要比规定起点的答案多除一个
格路计数问题
定义
-
在平面直角坐标系中,横坐标和纵坐标都是整数的点称为格点,平面格路是指从一个格点到另一格点只走格点的路,格路的长度是指其所走的路的步数.
-
对于一条从
到 的格路,若其只使用了上步 ,右步 ,则我们称其为 自由路. -
记
为 自由路的集合, 为 自由路数量,即 的元素个数,显然 . -
对于一条从
到 的自由路,若其始终不经过对角线 下方,则我们称之为 路. -
记
为 自由路的集合, 为 自由路数量,即 的元素个数. -
对于从
到 的 条格路 ,其中 .若 ,则我们称格路 等价.将 的等价格路全集记为 . -
对于任意格路
,记 ,则 .定义 的周期为使得 的最小数 ,用 表示,则显然有 .
定理
散模型
多叉堆计数
有一棵树,要求给每个点一个
不妨设以
那么考虑根的答案
也就是说,
Example1([AGC060C] Large Heap)
如果没有限制,就是一个简单的多叉堆计数.
而有了限制怎么做呢?我们考虑把
Example2([HEOI2013]SAO)
显然给出的是一张树形图,然后每条边有一个限制表示这条边所连接的两个点哪个更大.现在给每个点一个
我们随便找一个点然后当成有根树做,然后如果只有父亲小于儿子的边就是简单的多叉堆计数.不然,我们可以做一个简单容斥.这样问题就又转化回多叉堆计数,容斥部分写一个树形dp就好.
补一下,这个树形dp没有那么简单.首先你注意到多叉堆计数是跟子树大小有关系的,所以你不能简单地设计
但是注意到这题的容斥系数是
这个故事告诉我们别什么容斥都最后算,你能在做的过程中把
三元环计数
我们对原图建立一个新的有向图,在新图中,如果
接下来枚举原图的一条边
四元环计数
仍然类似三元环计数那样建立新图.
考虑原图中的两条边
有标号DAG计数
即:
证明见反演与容斥-子集反演-Example2.
Example1(qoj5749)
注意到一个环内部不能有任何边,那么其实也就是有标号DAG计数,只不过要乘上一个斯特林数.不妨设
逆用斯特林公式,如果
注意到
评论