很多人说,图论就是背模板。
对于算法来讲是如此,但是我们在做题的时候,遇到的最大 的问题其实是如何转化为图论模型。
经常会发出“这竟然是一道图论题!”这样的感叹(比如我 在做2021年联合省选的时候)。
所以这节课,不仅介绍一些经典算法模型,选择的例题多为 需要转化问题的题目。
最短路
P6961 [NEERC 2017] Journey from Petersburg to Moscow
P6961 [NEERC 2017] Journey from Petersburg to Moscow。
用到了图论中的经典技巧,以 为分界点。
枚举每一条边为第 大的情况,然后将所有边的边权减去这条边的边权,然后将负数变成 。
这样的话,比 大的就不用算了。
然后怎么证明这个的正确性呢?
如果真实的比 小,也就是 多了,这样的话答案一定会更大,因为减去的要加回来。
如果真实的比 大,也就是有很多没减成 的,这就会导致程序考虑不需要考虑的东西,答案就更大了。
P5304 [GXOI/GZOI2019] 旅行者
建立超级源点和超级汇点。
然后需要找到超级源点到超级汇点的路径。
不能分治,因为分治太慢了,节点需要全部用满。
然后我们想到了二进制分组,就是进行 次,然后每一位相同的分在一起。这样不重不漏。
怎么更快?
换一个思路,枚举中间的点,然后看到他最近和他能到的最近的点凑成的路径。
两次 dij 可以完成。
P6880 [JOI 2020 Final] 奥运公交 / Olympic Bus
P6880 [JOI 2020 Final] 奥运公交 / Olympic Bus。
好好读题,是一开始就反转。
好像不是分层图,因为这次翻转对下次有影响。
暴力就是枚举每条边翻转,然后 dij。
我们发现没有必要,因为如果这条边不是最短路上必经的边直接做对答案没有任何影响。
枚举每一条边,如果不是 或者 的必经边,就可以直接贡献答案。
如果是的话,需要反转了再 dij。
这样复杂度是正确的,dij 用 的。
P2371 [国家集训队] 墨墨的等式
经典的同余最短路模板题。
首先差分一下,。
然后我们发现,我们可以先找出最小的 ,然后每一个可行的 , 也可行,所以只需要找到最小的 是每一个值的就行了。
然后有一个很阴的 Hack,最小的 是 ,可以选择最大的。
P9140 [THUPC 2023 初赛] 背包
同余最短路。
选择性价比最高的物品的体积来作为同余最短路的那个模数。
对于 的,需要比较 和 ,相当于比较 。
然后需要结合数据范围中 很大来说明,因为只有这样, 的实际大小才没有影响。然后数据范围保证了 ,所以是可以的。
最后答案就是 。
Trick:为了防止负权边,而且解决要求的是最大路径的,还需要处理一下, 就是相对于最大的扣除的贡献(其中这个式子同时乘了 ),这个代价需要最小。
最后的结果:。
AT_arc084_b [ABC077D] Small Multiple
AT_arc084_b [ABC077D] Small Multiple。
编号怎么乱了?
如果这不放在图论里,我显然不会用图论做。
表示对 取模为 的数位和的最小值。
就是同余最短路。
和 转移,相当于模拟数位进位,然后需要找到一个 的倍数的。
01 bfs 会更快。
P7515 [省选联考 2021 A 卷] 矩阵游戏
不是,这玩意儿如果不是在图论里我绝对想不到图论。
首先,我们先当这不是个图论题。
稍微尝试一下就会发现题目最恶心的限制是 其每个元素为大小不超过 $10^6$ 的非负整数。
因为我们可以先瞎写出第一行和第一列的,然后后面的就可以直接确定了。
然后令现在的为 数组。
我们需要调整 数组,可以这样:
(不想写表格,ctj 不过分吧)
我们将限制条件写出来:
这还是没法做,但是这让人想起了差分约束。
然后换一下元,让 ,。
警示后人
首先是多测没清空,需要仔细检查,比如记录负环的 cnt 数组,或者你让 作为超级源点,这也要清空(虽然不会错)。
还有就是你如果用 cin/cout 并且关闭了同步,需要注意不能与其他输出方式混用,不要为了省事写 puts。
还有就是提醒一下 TLE50 的,建议稠密图用 vector。
P5905 【模板】全源最短路(Johnson)
我们想用 dij,但是发现有负权边。
所以我们需要改一下形式,边权变成 。(如果是 需要反边,有点麻烦吧)
然后 需要保证每一个 都大于等于 ,我们发现这是三角形不等式,,使用 SPFA 预处理。
然后就可以 dij 了,最后的 dis 需要 。
最小生成树
常见性质:
同一权值边的数量固定
对于任意一个带权无向图,其所有可能的最小生成树中,每种权值的边的数量是固定的,即由该权值的边组成的多重集合(考虑边权)在所有最小生成树中是完全相同的。
最小生成树是瓶颈生成树的充分不必要条件
无向图 的瓶颈生成树是这样的一个生成树,它的最大的边权值在 的所有生成树中最小。最小生成树是瓶颈生成树的充分不必要条件。
反证法,如果最小生成树的最大的边拆掉,换成瓶颈生成树中的一条将会得到更小的生成树。
P4208 [JSOI2008] 最小生成树计数
性质:对于任意一个带权无向图,其所有可能的最小生成树中,每种权值的边的数量是固定的,即由该权值的边组成的多重集合(考虑边权)在所有最小生成树中是完全相同的。
证明可以用 Kruscal 的过程证明。
还需要一个性质:
在处理完所有权值小于等于某个值 的边后,图中顶点被分成的连通块(即哪些顶点在同一个连通分量中)在所有不同的最小生成树中是完全一致的。
如果不一致,那后面加的边一定没有前面优。
有了这两点性质,我们就可以做这道题了(不用矩阵树定理也行)。
CF888G Xor-MST
这道题是用 Boruvka 算法。Boruvka 大概是对于每一个联通块,找出离他最近的块连接,循环这个操作。
P5236 【模板】静态仙人掌
这篇 tj 讲的还是很清楚的。
2-SAT
P5332 [JSOI2019] 精准预测
这道题是 2-sat。
建边什么的还是比较模板的,就是二维,点 表示 在时间 活着。
如果 死了,那么 也一定死。
还有就是预言, 的话 , 就是 。
第一个问题:建不下图,因为点太多了,所以我们可以只保存有需要的,然后就可以了。至于 就是离散化后找到下一个。
不想写证明了,挂篇文章。
网络流问题中,给定一个有向图 ,每条边 有一个非负容量 。指定源点 和汇点 ,求从 到 的最大可行流量,即最大流问题。
增广路与反向边
所有最大流算法都基于增广路定理:当前流 是最大流当且仅当残余网络中不存在从 到 的增广路。残余网络包含原图所有边以及反向边,反向边允许“撤销”之前不满意的流量分配,使算法能够不断调整至最优。
Ford-Fulkerson
最朴素的思想:在残余网络中任意找一条增广路(通常用 DFS),将路径上的最小残余容量加到答案上,并更新正向边和反向边,重复直到没有增广路。
正确性:依赖于最大流最小割定理,只要算法终止,结果就是最大流。
复杂度:,其中 是最大流值。当容量为整数时有限步终止,但可能很慢(例如容量很大时)。若容量为无理数,甚至可能无限循环。
Edmonds-Karp
Ford-Fulkerson 的改进:每次用 BFS 找最短增广路(边数最少),可以保证增广次数为 ,总复杂度 。
为什么选最短路径? BFS 保证了每次找到的路径是当前残余网络中的最短路径,从而可以证明每次增广后汇点 到源点的距离严格增加,因此增广次数有限。
Dinic 算法
Dinic 算法在 Edmonds-Karp 的基础上更进一步,通过分层图在一次 DFS 中寻找多条增广路,极大提高了效率。
BFS 建分层图:从 开始 BFS,只经过还有容量的边,记录每个节点的层次(到 的最短距离)。如果无法到达 ,算法结束。
DFS 多路增广:在分层图上从 出发进行 DFS,只允许流向层次恰好为当前层+1的节点,找到一条增广路就立即增广,并继续从当前节点尝试其他分支(即多路增广)。利用当前弧优化避免重复遍历已经流满的边。
重复步骤1-2,直到 BFS 无法到达 。
BFS 建立的分层图保证了所有从 到 的路径长度都是当前残余网络中的最短长度。DFS 严格按层次递增方向走,确保找到的增广路都是最短路径。这一定位使得我们可以证明一个重要引理:
每完成一个阶段(即找到阻塞流后),汇点 的层次必然增加。
因为反向边不会在同阶段被用于正向增广(它们指向低层),所以填满某些边后,下一阶段的最短路径长度至少增加1。由于节点数有限,阶段数不超过 。每个阶段内寻找阻塞流的复杂度为 ,因此总复杂度 ,远优于 Edmonds-Karp。
P1344 [USACO4.4] 追查坏牛奶 Pollutant Control
P1344 [USACO4.4] 追查坏牛奶 Pollutant Control。
求中间用的边的数量就将边权乘上一个很大的值然后加一就行了,只需要一次。
P3381 【模板】最小费用最大流
直接贪心,选取最小代价的增广路。
建议使用 EK。
P2045 方格取数加强版
网络流建模也很困难。
多次走只算一次的让我们想到了网络流。
我们发现这道题是有两个维度的,路径限制和数字和。
路径是最多 条,对应到网络流上就是流量被限制为 。然后费用我们需要让它大,最大费用流。
然后我们要用一个技巧:拆点,就是把一个点拆成两部分,我们拆成 和 ,就可以计算中间的边权作为点权了。
超级源点向 连边,流量 ,费用 。
还有,这道题其实很简单,不会出现负环。
P3358 最长k可重区间集问题
这怎么想到网络流?
先离散化,然后 就在 以内了。
我们发现这道题有一个 的限制,我们转化一下,就是有 条路径,每一条可以选择一些互不相交的区间,然后最大化最后的费用。
建边方法:
到 是流量为 费用为 。
到 是流量为 费用为 。
到 是流量为 费用为 。
到 是流量为 费用为 。
最小费用最大流。
CF277E Binary Tree on Plane
我也不知道怎么想到网络流。这道题我们需要从上向下思考,然后覆盖过程有点像网络流?
反正就这样吧,从源点向所有节点连流量为 的边,表示最多 个儿子,从节点向汇点连流量为 的边表示这只能从一个父亲出发。
然后点之间,就是父亲连向儿子。最后形成的路径是 。
然后费用为距离,最小费用最大流。
但是有一个问题就是这样无法保证父子关系长度,有可能路径中间只有一个点。
于是我们有想到了拆点,也就是将一个点拆成两半, 连接左边的, 连接右边的,中间就是第一个点的左连第二个的右。
这样的话,我们就可以让每一条网络流路径都是边了。最后判断答案是否可行就看流量是否为 。
CF863F Almost Permutation
先简化一下问题,我们根据条件,可以求出 的取值范围 。
然后大概建一下模:
然后,一个不好处理的就是平方。物理运动学做多的都知道,这是一个 这样的序列,也就是边权依次增加。
我们想办法要让最后加上这个值,可以通过流量限制。
也就是:
总结:流量还有限制和后效性作用,可以一定地记录中间的情况。
P4249 [WC2007] 剪刀石头布
反正我不知道该怎么想到网络流。
错误思路
将网络流的图设成 。
拆点可以限制路径长度,然后用流量来限制 和 是否相等。
也就是开头的边的容量为编号,中间为正无穷,最后的点向 连的边,容量比编号大的都要设置费用。
显然没有那么简单,因为忽略了两点之间的胜负固定了只有 种。
所以还是 ctj 吧。
这种环的问题可以转化成度。
如果没有三元环,那一定一个入度为 ,一个入度和出度都为 ,还有一个初读为 。
所以我们选一个,从入度来看。
如果入度为 会少一个三元环,如果是 就是 个,找出规律,会少 个,所以最后的答案就是:
然后就感觉跟上一道题很像了(好像上一道题原本也是黑,然后降了)。
然后就是如果 增加,就会有 的代价。
完了,我脑子的 cpu 烧了(其实昨天是电脑)。
我们将原来的边设为网络流中的点。
(容量不够,只有一个成立)
最大权闭合子图
技巧:就是分成左右两个集合。
我的总结。
P2057 [SHOI2007] 善意的投票 / [JLOI2010] 冠军调查
P2057 [SHOI2007] 善意的投票 / [JLOI2010] 冠军调查。
最大权闭合子图???
一个技巧,这道题 S 连接赞成票的人,T 连接反对票的人,进行最小割。
我们将朋友相连,如果他们不同,可以选择改变一个的观点,也可以不改变。在网络流中的体现就是最小割。改变就是割边变成和 的连边加上这个点在 这个集合的朋友。
P4313 文理分科
假如我们知道这是网络流的题。不是。
我们如果不知道这是网络流的题,可以把文科节点放左边,理科放右边。
向所有点连接容量为 的边,所有点向 连接容量为 的边。
然后我们发现这道题还有 系列的,可以新建节点单独计算。
向 连接容量为 的边,然后 向这五个点连接 的边(表示必须连接)。
同理。但是注意不要把边建反了。
总方案数减去最小割就行了。
P3227 [HNOI2013] 切糕
既然是 切 了,那就是将这个东西分成上下两部分,理所应当想到最小割。
我们建图, 向第一层的点,第 层连接 ,容量为 (割不掉)。
然后就是中间的点,第 层向 层连接容量为 的边。
接着我们需要处理这个相邻的间距 的限制,我们直接连个割不掉的边就行了,从 向相邻的 连边。
在草稿本上模拟一下:
| |
|. |
| . |
| . |
| .|
| |
(中间的边方向是从左到右)
要把这两个隔断显然不能从左边的高点和右边的低点个割。
P3749 [六省联考 2017] 寿司餐厅
如果我们考场上得知这是网络流的题,我们因该回去往最大权闭合子图上想。
至于怎么做?我们发现,如果选择了 ,一定会去选 和 。
然后每一个点的权值是 。
如果大于 ,就 向他连边,表示割掉的代价,否则向 连边,表示选择的代价。
然后还有就是如果选择了 ,那一定会向 连边,然后对于所有 都需要向 连接 的边。
最后的答案就是向 连的边的总长度减去最小割。
CF903G Yet Another Maxflow Problem
CF903G Yet Another Maxflow Problem。
这道题数据范围很大。
我们可以换个问题,直接算最小割。
在 中会可能有一个割点, 中也有可能,然后中间也有一些。
此时,答案是 。
然后还有 都不割的情况,就建边权为 的即可。
现在的问题是,怎么快速求出:
目前,这道题已经跟网络流没什么关系了考虑数据结构。
我们将 固定,然后需要维护的是:
我们需要改变的是 中的边的容量,所以上面的式子的值是不变的。
然后线段树。预处理和询问的两棵树可以只写一颗,区修查询全局最小值。
上下界网络流
P14578 【模板】无源汇上下界可行流
直接抄 OIWIKI 的。
首先,每条边有最小限制,所以我们先让这条边先流那么多。
然后,设流入流量减初始流出流量为 。
若 ,此时流量平衡,不需要附加边。
若 ,此时入流量过大, 向其连流量为 的附加边。
若 ,此时出流量过大,需要向 连流量为 的附加边。
在建图完毕之后跑 到 的最大流,若 连出去的边全部满流,则存在可行流,否则不存在。
有源汇上下界可行流
新建一条从 到 ,限制为 的边。
然后新建源点和汇点 ,建图就行了。
P14579 【模板】有源汇上下界最大流
在可行流的基础上怎么做?
我们跑完了可行流之后,删去加的附加边。
然后在原来的基础上跑网络流。
P14580 【模板】有源汇上下界最小流
与有源汇上下界最大流类似,答案为可行流减去残量网络从 到 的最大流,可以理解为要退掉尽可能多的流。
P7173 【模板】有负圈的费用流
对于网络中的负边 ,我们先让其直接满流。
然后加入 ,费用为原来费用的相反数,相当于进行退流。
然后就是相当于有上下界最小费用最大流。
P4843 清理雪道
这道题直接上下界费用流。
直接建出图之后保证下界为 就行了。
CF708D Incorrect Flow
首先考虑在这道题怎么建边。
对于 的边:
- :。
- :。
- :。
对于 的边:
(在 的情况下,先将基础代价 加到答案 Ans 中)。
- :。
- :。
- :。
建了这些边是为了满足原边的上下界网络流的限制(限制只能是那个流量),然后通过花费代价调整使其满足要求。
二分图
这个。
把讲义喂给 DeepSeek,然后...
对于一张图 (无孤立点,否则边覆盖可能不存在),有:
-
边覆盖:一个边集 ,使得任意顶点 都与 中至少一条边关联(即每个顶点都被覆盖)。
-
匹配:一个边集 ,使得 中任意两条边没有公共顶点(即每个顶点至多与一条边关联)。
-
点覆盖:一个顶点集 ,使得每条边 至少有一个端点属于 。
-
独立集:一个顶点集 ,使得每条边 至多有一个端点属于 。
这些概念之间有着密切的数量关系,下面是两个重要的定理(证明已在PDF中给出):
-
最小边覆盖与最大匹配:若图不含孤立点,则
证明思路:先取一个最大匹配 ,它覆盖了 个顶点。为了覆盖剩下的 个顶点,至少需要添加 条边(每条边覆盖一个新顶点),因此最小边覆盖大小为 。
-
最小点覆盖与最大独立集:
证明思路:独立集 的补集 是点覆盖,反之亦然,两者构成一一对应。因此最大独立集对应最小点覆盖,且大小之和为 。
这两个关系说明,对于任意图,如果我们能求出最大匹配,就能得到最小边覆盖;如果能求出最小点覆盖,就能得到最大独立集。而在二分图中,由于有 K?nig 定理(最大匹配 = 最小点覆盖),我们可以通过最大匹配同时求出最小点覆盖和最大独立集,进而也得到最小边覆盖。这为后续网络流求解二分图相关问题奠定了基础。
二分图最大匹配
在二分图 中,左部 ,右部 ,匹配是边集 ,使得任意两条边无公共顶点。最大匹配即包含边数最多的匹配。
网络流求法
- 建立源点 和汇点 。
- 从 向左部每个点连容量为 的边,表示每个左部点最多匹配一次。
- 从右部每个点向 连容量为 的边,表示每个右部点最多匹配一次。
- 对原图中的每条边 (),连 容量为 的边。
- 跑最大流,最大流量即为最大匹配数,时间复杂度 。
二分图最小点覆盖
点覆盖是顶点集 ,使得每条边至少有一个端点属于 。最小点覆盖即包含顶点数最少的点覆盖。
Konig 定理:在二分图中,最大匹配的大小等于最小点覆盖的大小。
因为最小点覆盖大于等于最大匹配。
然后构造大小为最大匹配的点覆盖:
跑完最大流后,令 为残余网络上左部中源点能到达的点与右部中源点不能到达的点。则 是点覆盖:若一条边左端不在 中(即左端不可达),则右端必在 中(因为若右端可达,则左端可通过该边到达,矛盾);同理,若右端不在 中,则左端必在 中。故所有边被覆盖。而 等于最小割容量,即最大流值,也就是最大匹配数。
因此最大匹配 = 最小点覆盖。
P4251 [SCOI2015] 小凸玩矩阵
这道题我们发现,一个行只能匹配一个列,一个列也只能匹配一个行。
那就 向行连边,列向 连边。
那个 很烦,用一般的技巧,二分答案,问题就变成了是否有至少 个数,使得这些数不大于当前值。
然后将矩阵中的这个值小于等于二分值的东西的 行向 列连边,二分图最大匹配。
这样限制了一行或者一列只能被用一次。
P2764 最小路径覆盖问题
比较妙的。
考虑转化问题,这个问题相当于给定一堆路径,然后需要进行合并,进行更多次的合并。
每一个点只能由最多一个前驱和最多一个后继。
所以考虑拆点,每一个点有前驱后继,然后前驱后继进行二分图最大匹配。
CF1592F2 Alice and Recoloring 2
CF1592F2 Alice and Recoloring 2。
也不知道这是怎么想出来的,就积累一下 Trick 吧。
首先,二三操作可以用两次一来代替,可以直接不考虑。
关于操作的题目有一个小技巧:寻找操作中的不变量。(tj 上的)
然后利用这个 Trick:关于区间操作的一些问题直接利用差分的思想,。
此时 是从 推出来的,但也可以直接推回 。 的反推的过程就相当于还原差分。
然后我们发现,操作 按照 的定义,只有 改变了。
操作 中 ,,, 发生了改变。
然后又是一个性质了:不会同时使用 和 。同理不会同时使用 和 。因为这可以用四次 来代替,所以我们不需要。
接着,除非 , 和 都为 ,才会使用 ,不然可以用两次 解决掉。
此时,第四个操作就会有限制了:
- 一行最多被操作一次。
- 一列最多被操作一次。
- 这个矩阵能被操作当且仅当 , 和 都为 。
直接二分图最大匹配。
所以大体思路:将一个操作弄成最优,然后剩下的全用普适性操作。
每一个四操作可以节省 ,总数减去匹配数即可。
二分图完美匹配与 Hall 定理
Hall 定理
对于二分图 ,存在一个匹配覆盖 中所有顶点(即饱和 的匹配)当且仅当
其中 表示 在 中的邻点集合。
证明概要
- 必要性:若存在饱和 的匹配,则 中每个顶点在匹配中有一个不同的邻点,这些邻点都在 中,故 。
- 充分性(利用最大流最小割定理):构造网络流:源点 连每个 (容量 1),每个 连汇点 (容量 1),原边 容量 1。则最大匹配值等于最大流值。
对任意 割,设 为割中未被割掉 边的 中点集,则 必须全部割掉与 的边,否则存在增广路。割的容量至少为 。由 Hall 条件 得该值 ,故最小割 。由最大流最小割定理,最大流 ,即存在饱和 的匹配。
CF338E Optimize!
给定一个长度为 的序列 和一个长度为 的序列 。求 有多少长度为 的连续区间和 完美匹配。
两个序列完美匹配当且仅当存在一种各自打乱顺序的方案使得两个序列对应位置上的数的和都不小于 。
不需要 Hall 定理?
对于在序列上难以解决的问题可以考虑在值域上解决(可以先离散化)。
等价于 。
用 把 替换。
然后我们操作变为判断一个区间能否满足存在排列 使 ,单点修改序列 。
建出值域线段树,序列 上的为后缀减操作,序列 为后缀加操作,查询是否存在有值小于 。
这个过程能用 Hall 定理解释?!
CF1009G Allowed Letters
首先是贪心,我们从前往后考虑这个,然后判断当前是否能这样填。
也就是我们一步步确定前面的值。
然后我们发现,这是一个类似二分图的东西,有 个位置和 种字母的很多副本,然后需要进行匹配。
有一个比较暴力的做法就是网络流,直接暴力在判断当前是否可以的时候网络流进行匹配。
但是显然会超时,我们需要利用好性质。这是二分图,我们当然需要用二分图的性质。所以我们掏出了 Hall 定理。
根据 Hall 定理,我们可以在当前连到最优之后判断所有子集,看看是否存在匹配,也就是后续有没有解。
我们发现左边的很多,然后右边的有一个限制就是字符种类为 。然后我们想一下就会发现,一个颜色的点连出的边是相同的,所以只需要 个点,然后同时匹配,因为如果集合不完整的话集合的邻居不变。
Two-Sat
网络流。
问题本质
最小割本质上是一个 整数规划问题。
问题的最终目标就是最小化:
表示选 的代价, 表示 是否在 这边。
最大权闭合子图
给一个有向图,每个点有可正可负点权,要求选一个点的子集,点权和最大。有一些限制 表示 选了则 必须选。
首先,正的选了有代价,负的不选有代价。然后限制中的有无穷代价。
常见技巧&模型
-
无穷的边强制连接。
-
把一边的变量取反。
-
拆点常见用途:
- 限制边权。
- 表示不同状态,方便获取。
-
对于多选一的问题,可以用一条链,限制只能割一个点。
-
绞尽脑汁定义变量,例如 。
-
选了有收获有代价的问题,收获连 S,代价连后面的。
-
方格特殊性质:可以弄成二分图,然后白点的变量表示是取了,黑点的表示是没取。
-
对于抽象点的问题纸上乱画画。。。
例题
P8215 [THUPC 2022 初赛] 分组作业
P8215 [THUPC 2022 初赛] 分组作业。 这道题的变量:是否选择愿意,是否选择合作。
-
不愿意 不合作,无穷的边。
-
A 不合作 B 且愿意 有 的代价。
-
A 不愿意且 B 合作 有 的代价。
-
愿意和队友不愿意 有 的代价。
P14832 [THUPC 2026 初赛] Unpair Ampere
P14832 [THUPC 2026 初赛] Unpair Ampere。
连边技巧:看如果怎么样,就一定会怎么样,充分条件有什么。
技巧:为了防止多割,割的代价加上一个大常数,最后再减掉。
设置必须变量->设置被动变量->有必要的时候对变量取反
首先想到的定义变量时发电厂是否转换。
我们发现这样做不了,因为不知道每个节点是否被火力/太阳能连接。
所以我们设置一个被动的变量,表示这个节点是否被火力/太阳能连接。
但是...这样好像有问题,同时被火力和太阳能连接不符合 。
所以我们尝试反转太阳能节点。
还有就是“可能存在一些设施直接或间接地同时连接到”,所以我们需要保证贡献传播。
然后源点也要反转。源点我们时进行了拆点的。
定义不被太阳能连接时 。 表示源点不反转。
-
, 如果被火力连接, 也必须,所以 。
-
, 不不被火力连接, 也要不不被火力连接,所以 。
-
就是不反转所以 一定被火力连接,。
-
不是不反转所以 一定被太阳能连接,。
-
被火力连接且不不被太阳能连接,就要花 ,。
为了防止一个电厂又是火电又是太阳能,就是两条边都被割掉了,所以我们需要给割边加上一个大常数,最后减去。
P2774 方格取数问题
方格有一个特殊性质,可以弄成二分图。
然后白点的变量表示是取了,黑点的表示是没取。
P6054 [RC-02] 开门大吉
跟 P3227 [HNOI2013] 切糕 差不多。有一个技巧,变量这样定义:。
还是这个图:
| |
|. |
| . |
| . |
| .|
| |
(中间的边方向是从左到右)
要把这两个隔断显然不能从左边的高点和右边的低点个割。
这道题是多选一,就一条链,限制只能割一个点。
思路
就是个缝合。。。为什么非要求一遍期望 。
然后有 表示选手 做第 套题。
-
,边权 。
-
,边权 。
还有神秘剪枝:if(rest>inf)return inf;。
P2762 太空飞行计划问题
思路
首先一些变量是这个仪器选不选。
但是问的是收益最大,我们看看哪些不行。
源点向实验连收益。实验需要向它所需的所有仪器连接 的边。仪器向汇点连价格。
然后怎么输出方案?
我们 dinic 最后一次检查中,会保存每一个点的 ,能到达的就是 S 集。
P5934 [清华集训 2012] 最小生成树
如果当前边可以放在最小生成树上,去除这个边,只保留比它小的,剩下图中 不联通。
思路
其实是性质题。
首先的性质就是如果当前边可以放在最小生成树上,去除这个边,只保留比它小的,剩下图中 不联通。
最大生成树同理。
然后建两棵树, 的和 的,然后分别跑 之间的最小割。
P5039 [SHOI2010] 最小生成树
跟上一道题有点像。
思路
除了那条边全部减就是那条边加。
然后对最后答案的影响就是跟那条指定的边的大小关系。
注意这道题是保证。
P4174 [NOI2006] 最大获利
思路
跟这个 P2762 太空飞行计划问题 很像。
AT_arc176_e [ARC176E] Max Vector
AT_arc176_e [ARC176E] Max Vector。
这道题我们可以通过最后的结果限制过程。
多选一还是用链来表示。
思路
首先把 拆成长度为值域的链, 也是。
然后我们建立虚拟点表示当前限制,每一个 建立一个。我们需要防止 和 都小于 的情况,所以把 Y 反过来,然后链接 上 这个点和 上的。
P12824 [NERC 2021] Kingdom Partition
P12824 [NERC 2021] Kingdom Partition。
代价有两倍,所以要建两条边,拆点实现。(这么逆天?)
思路
然后列出两个表格:
| ST | TS | SS | TT | |
|---|---|---|---|---|
| ST | 2 | 0 | 1 | 1 |
| TS | 0 | 2 | 1 | 1 |
| SS | 1 | 1 | 0 | 2 |
| TT | 1 | 1 | 2 | 0 |
对比题目要求的系数矩阵:
| A | B | C | |
|---|---|---|---|
| A | 2 | 0 | 1 |
| B | 0 | 2 | 1 |
| C | 1 | 1 | 0 |
然后 A-ST B-TS c-SS/TT。
P11531 [THUPC 2025 初赛] 检查站
拆点可以限制每一个点的流量为 。# 二分图
对于一张图 (无孤立点,否则边覆盖可能不存在),有:
-
边覆盖:一个边集 ,使得任意顶点 都与 中至少一条边关联(即每个顶点都被覆盖)。
-
匹配:一个边集 ,使得 中任意两条边没有公共顶点(即每个顶点至多与一条边关联)。
-
点覆盖:一个顶点集 ,使得每条边 至少有一个端点属于 。
-
独立集:一个顶点集 ,使得每条边 至多有一个端点属于 。
还有:
-
交错路:由匹配边与非匹配边交错而成的路径;
-
增广路:始于未匹配点且终于未匹配点的交错路.
利用定义解题
二分图的性质:没有奇环。
还可以用模板的匹配解决一些基础一点的问题。
时间复杂度(匈牙利算法):。
CF1537F Figure Fixing
这道题是二分图定义性质题
首先,我们特判掉奇偶性不同的。
然后,这道题中,我们需要先考虑哪些情况是可以随便填的。
然后我们发现奇环上的点可以任意加一个偶数的东西,就相当于在这个点加上 ,旁边的一人加一个 。
但是这个结论不足以做这道题,我们需要扩展。我们看与奇环联通的点,随便加 贡献都可以转移到环上。
所以奇环是可以的。
然后其它情况就是二分图了,二分图只需要看左右的差量是否正确就行了。
CF1684G Euclid Guess
这个题是性质题+构造
不要看错题了,数对构成的序列 ,而不是序列两两进行。
首先,我们发现 的限制很不好。
-
一定可以构造出来 。
-
,我们无法构造。
-
,构造 ,,需要满足 ,就是 ( 不行,因为会成为 )。(后面成为大元素)
然后我们发现,大的元素一定会占用一个小的,对应上面就是 。
然后小的元素可以被大的使用,也可以自我消耗,所以我们需要尽可能少用小的元素。
我们直接让 ,于是记录 ,然后进行 ,接着记录 ,然后进行 ,此时如果 就结束了。
因为无论如何,我们都需要用到 的因数(这是辗转相除,很妙)。
所以最后,我们对于每一个大元素 需要匹配小元素,直接二分图匹配, 且 的有边。
所以题目里要求最后构造出来的总对数 这个条件其实没用。
P2764 最小路径覆盖问题
这个题是二分图建模,然后利用拆点的性质
给定一个 DAG,用最少的不交路径覆盖所有的点。
这道题是不交路径,所以我们可以设置每一个点只有一条出边和入边,这个限制可以用我们学过的拆点来限制。
然后二分图最大匹配就行了(网络流写过了)。
现在有一个升级版,就是用最小的可重复路径覆盖所有的点。我们可以找到最小路径覆盖,然后可重的就是可以绕过去。
CF1728F Fishermen
这是一个性质题,需要简化题目的问题,然后结合二分图可以找到左边字典序或者和最小的匹配方式。
思路
看完题后,我们需要先想想这道题的性质。
本题限制很多,尝试简化。
首先求的是最小的,那么 中间也一定是最小的了,所以这个限制可以先不用管。
还有限制: 这个限制可以通过排序直接去除掉,只需要保证 不相同就行了。
这样,一个数只能匹配一个 ,做二分图匹配就行了。
随便结合一下性质:二分图匹配可以找到最小的解。
注意匈牙利算法清空 需要在匹配成功后。
CF1620F Bipartite Array
这是一个性质题,需要观察出这道题的二分的性质
看完题肯定能发现性质:如果有长度大于等于 的逆序对,就不是二分的,因为这样会出现奇环。
所以我们发现,这道题中我们需要让 排成两个上升子序列,可以不连续。
所以可以直接 dp, 表示当第 位取正时,另一段末尾的最小可能值, 表示当第 位取负时,另一段末尾的最小可能值。
P1963 [NOI2009] 变换序列
字典序最小处理技巧,从后往前
如果没有字典序的限制,这可能就是绿。一个数位置最多有两个数可以放。
然后我们发现这个不能行的原因是,后面会去替换前面的最大的边,所以我们只需要先处理后面的,再处理前面的。
图博弈
两人在图上玩游戏。初始时,点 有一颗棋子。A 先手,两人轮流移动棋子。
棋子每一步走一条边,且不能走到已经走过的点,不能移动就输了,谁会赢?
结论:如果途中存在一个最大匹配不含 ,则 必败,否则 必胜。(这个结论并不仅限于二分图。)
结论证明
先证明包含 就必胜。如果所有的最大匹配都包含 , 第一步会走到一个 的匹配点,然后接下来 只能走一个非匹配边, 接着又会有匹配边,循环往复。最后一定是 走不动了,因为最后如果是非匹配边,一定有一种匹配是选择了这条边,因为这并不影响其他地方。
然后还需要向明不包含 必败。如果 不在最大匹配中,所以 所有的邻居都是匹配点,结合上面的, 必胜,即 必败。
模板题:P4055 [JSOI2009] 游戏
Konig 定理
定理内容
在二分图中:
证明
证明思路:找到显然的 或 ,然后证明 成立。
证明
我们发现 ,所以我们只需要构造一组大小等于最大匹配的最小点覆盖。
首先,用匈牙利算法求出图的一个最大匹配。然后,从左部的每一个未匹配点出发,走一遍“匈牙利算法”中的交错路(依次经过非匹配边、匹配边、非匹配边……),并标记所有访问到的点。
若左端点未标记,则它是匹配点(不然一开始就会被标记)。
若右端点标记,那它一定是匹配点。
然后对于点集:左部所有未被标记的点 + 右部所有被标记的点,这是一个大小 最大匹配的点集。
为什么?对于每一条边,如果左边的点被标记了,但是右边没有,那么这是匹配边,又因为如果这是匹配边,唯一到达左边的方法就是通过这条边,所以矛盾了。
所以每一条边左右都被标记了。
所以这也是一个点覆盖。
然后就得出了结论,在二分图中:
常见结论
关于点匹配边
这个还是用 和 证明。
证明
最小点覆盖的补集是独立集,这个集合大小 最大独立集。
最大独立集的补集是点覆盖,这个集合大小 最小点覆盖。
所以他们的和又 又 ,所以相等。
关于边匹配点
若图不含孤立点,则
同理证明方法:
和上面同样的证明方法
最小边覆盖的补集是匹配,这个集合大小 最大独立集。
最大匹配的补集是边覆盖,这个集合大小 最小点覆盖。
所以他们的和又 又 ,所以相等。
另一种证明方法(貌似更简单)
证明思路:先取一个最大匹配 ,它覆盖了 个顶点。为了覆盖剩下的 个顶点,至少需要添加 条边(每条边覆盖一个新顶点),因此最小边覆盖大小为 。
关于网络流
Konig 定理:在二分图中,最大匹配的大小等于最小点覆盖的大小。
因为最小点覆盖大于等于最大匹配。
然后构造大小为最大匹配的点覆盖:
跑完最大流后,令 为残余网络上左部中源点能到达的点与右部中源点不能到达的点。则 是点覆盖:若一条边左端不在 中(即左端不可达),则右端必在 中(因为若右端可达,则左端可通过该边到达,矛盾);同理,若右端不在 中,则左端必在 中。故所有边被覆盖。而 等于最小割容量,即最大流值,也就是最大匹配数。
因此最大匹配 = 最小点覆盖。
-
最小边覆盖与最大匹配:若图不含孤立点,则
证明思路:先取一个最大匹配 ,它覆盖了 个顶点。为了覆盖剩下的 个顶点,至少需要添加 条边(每条边覆盖一个新顶点),因此最小边覆盖大小为 。
-
最小点覆盖与最大独立集:
证明思路:独立集 的补集 是点覆盖,反之亦然,两者构成一一对应。因此最大独立集对应最小点覆盖,且大小之和为 。
这两个关系说明,对于任意图,如果我们能求出最大匹配,就能得到最小边覆盖;如果能求出最小点覆盖,就能得到最大独立集。而在二分图中,由于有 K?nig 定理(最大匹配 = 最小点覆盖),我们可以通过最大匹配同时求出最小点覆盖和最大独立集,进而也得到最小边覆盖。这为后续网络流求解二分图相关问题奠定了基础。
Dilworth 定理
最长反链:最大的子集使得互相不可达。注意,这是集合!
最小可重链覆盖是指用最少的几条可重路径把图中所有顶点都覆盖至少一次。
证明
取走一个没有入度的点。
最长反链不变。则直接把这个点接回去。
最长反链也减了 1,则把这个点作为一个单独的链加入。
反正感性理解一下。
P4298 [CTSC2008] 祭祀
这道题就是让我们求最长反链
Question 1
问个数就相当于问反链大小,根据 Dilworth 定理,最长反链 = 最小可重链覆盖。
所以我们只需要求最小可重链覆盖,怎么求?可重的好像不好求,我们先考虑怎么把问题转化为不可重链覆盖。
题解里说:Dilworth 定理原本的描述是对于偏序集来说的。你可以将偏序集理解为“求过传递闭包的 DAG”,于是“可重”或“不可重”就无所谓了。
也就是我们将问题转化成传递闭包,先处理一下再进行覆盖。相当于我们可以选择跳过一写点,这样处理之后,“可重”或“不可重”就无所谓了。
传递闭包可以用 Floyd 求。
然后既然是求不可重的,每一个点最多 条出点或出边,拆点,进行二分图匹配就行了。
Question 3
问题 需要问题 做铺垫?
对于普通的一条链,我们需要随便选一个点,且这是最优的。
对于两条链汇集的交点一定不是最优的,因为我们最好在分叉上选。
所以我们对于每一个点,假设选它。
Question 2
我们发现对于上面的链的情况,有一堆节点只能选一个,我们对相同排除就行了。
Floyd 枚举顺序别写反了。
CF1404E Bricks
二分图完美匹配与 Hall 定理
Hall 定理
对于二分图 ,存在一个完美匹配当且仅当
其中 表示 在 中的邻点集合。
使用归纳法证明,有点意思。
证明
假设二分图满足 Hall 条件。
如果不存在完美匹配,就取一个最大的匹配,它肯定没覆盖某个左边的点。
从这个点出发,交替走“非匹配边从左边到右边、匹配边从右边到左边”,把能走到的所有点找出来。
在这个可达集合里,左边的点(除了起点)和右边的点是一一配对的(因为匹配边),所以左边的点比右边的点多一个。
但所有左边点的邻居都只在这些右边点里,这就违背了 Hall 条件——邻居数反而比左边点数少。因此,Hall 条件成立时,完美匹配必然存在。
假设二分图不满足 Hall 条件。
即存在某个左边的子集 ,它的邻居数 。那么 中的点要匹配到不同的右边点,但邻居数不够,因此无法形成完美匹配。
网络流证明
证明概要
- 必要性:若存在饱和 的匹配,则 中每个顶点在匹配中有一个不同的邻点,这些邻点都在 中,故 。
- 充分性(利用最大流最小割定理):构造网络流:源点 连每个 (容量 1),每个 连汇点 (容量 1),原边 容量 1。则最大匹配值等于最大流值。
对任意 割,设 为割中未被割掉 边的 中点集,则 必须全部割掉与 的边,否则存在增广路。割的容量至少为 。由 Hall 条件 得该值 ,故最小割 。由最大流最小割定理,最大流 ,即存在饱和 的匹配。
AT_arc106_e [ARC106E] Medals
首先是二分图建模,这道题相当于是天匹配人,把每个人拆成 个,进行完美匹配,我们需要找到完美匹配。
由于是可行性,所以我们想到了 Hall 定理。
我们二分答案判断是否可行,判断的时候用 Hall 定理。
具体写法中 表示出勤员工集合是 的子集的天数,然后 mid-f[m-i] 表示连的边。
DFS 树
dfs 树就是 dfs 生成的树。
性质:没有横叉边。
所有叶子构成原图的独立集,因为叶子之间没有横叉边。
同深度的点也能构成独立集,这跟上面类似。
CF1470D Strange Housing
这道题就是 dfs 树的性质应用(其实没有利用任何性质)
给一个无向图。求一个独立集,使得只保留和独立集相连的边,图仍然连通。
这道题我们按照 dfs 的顺序选,能选就选。
证明就用归纳法,对于每一个 都能保证做完这个操作后连通。
P5811 [IOI 2019] 景点划分
主要思想:拆分化简问题。
考虑树的特殊情况,然后处理 dfs 树的返祖边
首先,为了让问题更简单,需要钦定变量顺序,我们设 ,然后需要满足 和 即可,因为我们如果选了 ,可以通过拆分 来得到 或者 ,所以只弄 和 是最优的。
然后我们发现这个图有点复杂了,于是我们先考虑树的情况,我们发现我们需要让树存在一条边,切掉之后左边大小 ,右边 ,即存在 的子树。
然后由于 ,所以我们想到了重心。我们先找到重心,然后,如果有解一定存在一个子树大小大于等于 ,然后剩下的拆成 就行了。
然后树的情况就做完了,我们想想图怎么做。
我们先建出 dfs 树,然后找出重心(类比刚才的特殊情况)。如果存在一个子树大小 就直接可行,否则我们需要考虑返祖边。
考虑返祖边就是看这个子树中的节点连接到的重心的祖先。具体写法就是直接向上,然后限制不能走重心。
以重心为根,每个子树(块)大小 。利用返祖边(连接重心祖先和重心儿子),可将多个子树连通。依次累加子树大小直至总和 ,将这些子树与重心一同作为 ,则 (因每个子树 ,累加刚达 时总和 )。
证明:由 得 。剩余部分点数 ,且原图连通,故剩余点中必有一连通块大小 ,取为 。
所以那个 的限制也限制了 和 的量级,从而更好地找到子集。
CF51F Caterpillar
性质结论题
首先,我们发现毛毛虫不能有环,所以先缩环。然后就变成了一个树上问题。
这时候,我们会猜结论:选直径!
怎么证明?我们模拟一下过程,就会发现叶子节点是不会合并的,直接合并父节点就行了。所以我们需要保留最多的父节点,于是就选直径了。
P3225 [HNOI2012] 矿场搭建
Tarjan 的应用
首先这道题肯定和割点有关。
对于每一个点双,我们发现,如果这个点双连接了两个及以上割点,都可以跑到别的点双里面。
然后否则就在这个点双中建立一个逃生点。方案数 。
然后如果没有割点,就是独立的,需要两个救生点,所以就是 。
注意写法
if(low[v]>=dfn[x]){
g[x]=1;
child++;
dcc++;
while(s.top()!=v){
d[dcc].push_back(s.top());
s.pop();
}
// d[dcc].push_back(x);
d[dcc].push_back(s.top());
s.pop();
d[dcc].push_back(x);
}
需要这样写,因为每一个 可能在不同强连通分量中。
圆方树
实在懒得讲了,反正大体思路还好,就放点例题吧。
P4630 [APIO2018] 铁人两项
圆方树的应用
注意:两个点也要算作点双。
首先,对于每一个 和 ,我们的答案就是两点的所有路径中的点的并集大小减二。
然后我们想到这个问题在树上更方便求解,于是我们需要圆方树。
此时我们可以把方点设为这个点双的大小。但是这时候我们发现,方点之间会有共同的节点,也就是割点,所以我们需要将路径中的圆点的权值设成 ,然后路径中的权值和就是路径的节点个数了。
令 为点权,对于节点 ,两个点都在子树中的情况:
然后我们发现这会有很多的重复的,就利用刚刚的点权进行容斥:
这样就能避免割点被重复统计。
还有就是这三个点互不相同,由于方点,会重复计算,所以直接在圆点就抵消掉。
CF1763F Edge Queries
圆方树简单应用
建出圆方树可以直接做,用 表示非割边的前缀和。
P4606 [SDOI2018] 战略游戏
有一个经典 trick:
- 树的 dfs 序求出后,假设按 dfn 排序后关键点序列为 。所有关键点形成的极小连通子树边权和的两倍为 。
圆方树应用+虚树思想
将原图转化为圆方树(原图中的点为圆点,每个点双连通分量建一个方点)。
在圆方树上,圆点权值为 ,方点权值为 ,并将点权转化为到父节点的边权(便于路径求和)。
对于每个询问的点集 ,将其按 DFS 序排序,计算相邻点(包括首尾)在树上的路径权值和,总和除以 得到包含所有 的最小连通子图的边权和。
这里不建出虚树了,就用虚树的思想。
加上该子图根节点(即排序后第一个与最后一个点的 LCA)的权值,得到子图中所有点的权值和,即圆点总数。
减去 即得到不在 中且删除后能使 不连通的圆点数量。
一个写法:记录路径权值不算 的,只有进入和出去会计算 。然后对于节点 就单独算了。
P8456 「SWTR-8」地地铁铁
这道题首先我们发现如果有环就可以选择任意一个方向。
所以我们想到,先建出圆方树。
- 对于在同一个方点的情况:
- 如果全是一个字母,答案就是 。
- 答案是 ,但是又有一种情况就是如果这个点从两边走,两边的路径上的点一边全是 一边全是 需要减去 。
- 其他情况类似:
- 对于普通的情况,如果一条路径同时存在白点双或黑点双,这一定可以。特殊的那种左边只有 ,右边只有 的一定可以有一种让两点混的方式。
至于写法,就需要好好想想了,不然代码会很长。这里的一边全是 一边全是 这种情况直接判断哪个有 和 的入度的个数 即可。
重链剖分
这里不详细讲解了。
P4219 [BJOI2014] 大融合
比较有用的 Trick:可以离线,倒叙做,然后转化成删边,用树剖做。
倒叙可以删除的时候上面的 全部减去下面的大小,下面的 全部减去上面的。
代码不想写了,写 LCT 吧。
长链剖分
就是按长度找出最长子树。
树上 K 级祖先
用长链剖分做这道题还是很奇妙啊,怎么想到的?
我们需要一个 的算法, 有什么算法?打表,显然,我们不能打完,所以我们需要打我们需要的。
首先,我们需要一个 表示这个 的二进制位的最高位(以下简写 )。
我们第一步是从初始节点 直接跳 到达 ,然后我们就会发现,现在 。
然后结合这个性质:
一个节点的 级祖先所在的长链长大于等于 。
我们看到,这个 的长链一定大于等于 ,所以也大于 。
所以我们如果预处理出来每一条链向上和向下的点,是不是可以快速做出来呢?
长链剖分优化 dp
即长链启发式合并。
这个和 dsu on tree 的不同就是按照子树深度来划分,主要维护带有深度的问题,然后是按照指针偏移来进行的转移。
虚树
老师说这个玩意儿完全不到 级。
大概思路就是 分治+去除冗余信息。
若询问至于部分节点形成的关键点有关,可以保留 关键点集+他们的 LCA。
可以证明, 个点的 LCA(两两凑成的)最多有 个,可以用哈夫曼树思想从深度最深的 LCA 合并来证明。
CF504E Misha and LCP on Tree
经典套路:哈希+二分,然后还需要述链剖分快速维护对比。
思路好想,代码不好写
代码好难调。。。
这道题我们需要求一条路径的哈希值,需要求出根节点到他的哈希值,还有他到根节点的,然后要写半天。
树上启发式合并
就不讲了,看这道题:
P4149 [IOI 2011] Race
我们发现如果设定合并内容为到当前节点的距离,会很难转移。
所以我们直接存这个点到根节点的长度,然后最后的答案就需要两点的距离减去 LCA 的距离的两倍。
点分治
dsu on tree 是根据子树大小确定最大的子树的贡献直接保留。
而点分治是直接计算重心,用重心进行子树的拆分来完成问题。
这个。
P3806 【模板】点分治
点分治通过每次选取树的重心作为分治点,将树分解为若干子树递归处理,从而高效统计所有经过或不经过当前重心的路径信息。
P6329 【模板】点分树 / 震波
我们通过点分治每次找重心的方式来对原树进行重构。
将每次找到的重心与上一层的重心缔结父子关系,这样就可以形成一棵 层的树。
-
性质 :树是 层的,而且树上所有点的子树大小之和为 ,所以这可以让很多暴力更快。
-
性质 :对于任意两点 ,唯一可以确定的是 在点分树上的 LCA 一定在 的路径上,。(这个感性理解一下,如果 LCA 不在就会出现环)。
然后结合这两个性质我们可以做题了。
这道题的思路
首先我们发现每一对节点的 LCA 个数是 级别的,所以考虑枚举 LCA。
,答案就是拿 的子树内到 的距离 的点权和 方向子树中到 的距离 的点权和。
对每个点 建一棵动态开点线段树,下标为 的位置维护 子树内所有 的 的和。
-
对于 子树内的 ,区间查询即可。
-
对于 在 方向上的儿子 的子树,考虑对于每个点再建立一棵动态开点线段树,线段树上下标为 的位置维护 子树内到 距离 的点权和,然后就可以解决了。
查询:从 沿点分树向上,设当前节点为 ,。若 ,则答案加上 中距离 的和,减去上一节点 的 中距离 的和。
修改:从 沿点分树向上,对每个 , 中下标 增加权值;若 有父亲 ,则 中下标 增加权值。
代码太难调了!!!
线段树合并
就是直接模拟合并。
时间复杂度:每一个节点会被合并一次,然后节点数虽然放到线段树上是 个,但是只会访问这 个中的一个,然后对于每一个节点,会被合并 次(可以尝试势能分析)。
P3521 [POI 2011] ROT-Tree Rotations
P3521 [POI 2011] ROT-Tree Rotations。
思路
我们发现,交换这个点只会改变左右子树间的贡献。
所以我们只需要计算所有点的左右子树间的贡献就行了。
对于每一个点,建一个动态开点权值线段树,线段树的合并就可以计算贡献了,左边 的和右边 的进行这种匹配。
简单总结一下,很多时候都是对于原树的结点,每一个都建立一个权值线段树,维护所有权值,进行合并。然后由于插入的权值数量有限,最后的复杂度也没有问题。
P8496 [NOI2022] 众数
这道题就是直接权值线段树,然后加上二分就行了。
至于删除最后一个数就是链表了。
树形 dp
P4577 [FJOI2018] 领导集团问题
这道题的状态设置成答案为 的时候的最好状态。
然后利用到这道题状态的有序性,直接放入 multiset。
思路
注意:部门不必联通!
表示在 的子树中选择 个点组成的所有树上 LIS 中,级别值 最小值最大的那一个。
然后利用到这道题状态的有序性。
然后我们建立 multiset ,里面的数按升序排列后,第 个数表示: 在 的子树中,选 个结点组成合法集合时,这 个结点中最大的权值最小可能是多少。
然后合并就是直接插入,很好理解。
最后答案就是 multiset 的大小。
长链剖分
P4292 [WC2010] 重建计划
其实这是一道点分治和长链剖分都能做的题。
常见的 trick:二分答案之后,将所有边权减去 mid 然后使最后答案 。
这道题的状态定义和长链剖分的本质密切相关
这道题需要定义一个 表示在 为 的节点上,到他所在的重链底端的权值和。
然后定义 表示 节点向下走 的路劲权值和减去 。
然后这样设计是为了同一条重链上的节点可以直接转移。
模板
矩阵运算
定义
拉普拉斯展开
, 为去除 行 列的子式。
三角行列式
若 为上三角或下三角矩阵,则 。
简单说一下,仅恒等排列 的项非零(其余项必含下三角含有 的元素,因为如果一项 对应的 ,一定有一项 )。
常见性质
常见性质
-
- 行列式转置后值不变。
-
- 交换两行(列),行列式变号;若两行(列)相同,行列式为 0。
-
- 一行(列)的公因子可提到外面。
-
- 若两行(列)成比例,行列式为 。
-
- 若一行(列)是两组数之和,可拆成两个行列式相加。
-
- 将一行(列)的倍数加到另一行(列),行列式不变。
计算方法
由这个:
把行列式的某一行(列)的各元素同乘同一个数然后加到另一行(列)对应的元素上去,行列式不变。
我们可以把行列式消成倒三角矩阵。
矩阵树定理
一个图, 为图的邻接矩阵,表示两点之间的边的数目, 为 的度数。
然后矩阵 。
然后去掉第 行与第 列( 任意), 的值即为生成树的个数。
如果带有边权
我们发现带有重边的情况矩阵树定理可以解决,然后变的个数会乘进答案里面,所以我们直接把边权设为边的个数。
如果是有向的
从根向外的外向树,A 表示入度。
从外向根的内向树,A 表示出度。
P6178 【模板】Matrix-Tree 定理
直接就是模板了,注意对于有向的,需要交换 节点和 节点,因为计算的时候需要减去 行 列。
例题
就记住板子,然后利用这个可以求树的边权的乘积就好了。
P3317 [SDOI2014] 重建
这道题是使用了的边的 乘上未使用的边的 ,我们不希望所有的边都要乘一边权值,所以我们设定初始权值为 ,然后边权为 。
P6624 [省选联考 2020 A 卷] 作业题
利用 得:
推完之后,我们只需要枚举 ,然后极端 倍数的生成树边权和。
然后怎么求 和 呢?
我们可以化和为积,在模 意义下,计算 。
加减不变。
乘法:
除法:
P5296 [北京省选集训2019] 生成树计数
这是什么东西!
P4336 [SHOI2016] 黑暗前的幻想乡
容斥
设 为用指定的 个公司,且不考虑每个公司都修建一条道路的要求,生成树的方案数。
CF917D Stranger Trees
由于矩阵树定理求的是乘积,我们就把重要的边标记成一个数就行了,然后 次项就是用了 次。最后选 个这种数,然后高斯消元解方程。
P4455 [CQOI2018] 社交网络
定时练习的题,但是是模板。