省选图论专题 2 做题记录

省选图论专题 2 做题记录

A P8456 「SWTR-8」 地地铁铁

\(\text{Link}\)

考虑正难则反,统计出两点之间简单路径只可能有一种颜色的点对数。这个有两种可能,一种是两点间只有一条纯色路径,另一种是两点间只有若干条点不相交的纯色路径。

考虑建出圆方树,那么第一个情况就是两点间的所有点双都是纯色的,可以简单用并查集缩点求出方案数。然后看第二种情况,既然两点间有两条点不相交路径,那么它们一定在一个点双里。同时发现这种情况一定满足下面的条件:同一个点双里只有两个点同时有两种颜色的出边。对每个点双暴力判断即可。复杂度 \(O(n+m)\)

B P9150 邮箱题

\(\text{Link}\)

我们先对 \((i,k_i)\) 建图,称此时建出的图为钥匙图。显然钥匙图是若干个环组成,我们对每一个环求答案即可。我们维护一个序列表示当前从起点开始已经走过的所有点,假如当前我们需要加入一个点 \(x\),则可以得到如下做法:

  • 先看最后一个点是否有指向 \(x\) 的边,有就将 \(x\) 加入序列,否则退出并计算答案。
  • 找到在这个序列中最靠前的,\(x\) 可以到达的点,将这中间的所有点合并为一个强连通分量。

做法正确性显然,而复杂度是 \(O(n^2)\) 的,考虑怎样优化。

一个显然的想法就是在一个环上如果知道了一个点的答案,能否快速算出它的入点的答案。先断环为链,从后往前扫并统计答案。这时我们扫的时候维护的不止是一个序列,而是若干条链,也就是当无法再走的时候新开一条链进行统计。那么加入一个点 \(x\) 的过程如下:

  • 先新建一个点 \(x\) 表示单独一个强连通分量。

  • 考虑当前第一条链的末尾节点有没有指向第二条链开始节点的边,如果有则将两条链合并。我们对每一个点维护一个 \(pre\) 表示它之前最后一个指向它的点,这样只需要判断第二条链开始节点的 \(pre\) 是否在第一条链的末尾强连通分量里即可。

    这里需要发现,能够进行这个操作的前提是第一条链只有一个强连通分量,原因在于如果不是那么在加入 \(x\) 之前这两条链就应该已经合并了。

  • 然后我们需要合并第一条链上的强连通分量,显然应该找出指向第一个强连通分量最靠后的强连通分量,将它们全部合并即可。

    这里我们需要分析一下怎样实现这个操作。我们对于每一条链维护一个 \(val\),表示这条链上最后一个有返祖边的点,那么当我们合并到这条链的时候,由于此时第一条链只剩一个强连通分量,所以 \(val\) 之前所有的强连通分量都可以合并。然后再回到第二步即可。

用并查集简单维护一下链和强连通分量,于是我们就可以在 \(O(n+m)\) 的复杂度内解决这个问题了。

C CF1515G Phoenix and Odometers

\(\text{Link}\)

首先显然考虑强连通分量缩点,显然我们一定是不断跑环以满足条件,那么假设所有环的长度分别是 \(l_1,l_2,l_3,\cdots,l_k\),那么根据裴蜀定理,我们要求 \(\gcd(l_1,l_2,\cdots,l_k,t)\mid s\)。于是我们自然要求出 \(\gcd(l_1,l_2,\cdots,l_k)\)

不过这个环直接数比较困难,因为我们是在 SCC 上数。我们想把它变成无向图,这样就可以直接跑 DFS 树了。此时发现,如果我们有一条边 \((u,v,w)\),那么我们可以认为它还有一条边 \((v,u,-w)\);原因在于 SCC 上一定有一条 \(v\to u\) 的路径,把这个路径和这条边组成的环跑 \(t\) 遍后的贡献相当于 \(0\),那么少跑最后一条边就相当于从 \(v\) 走到 \(u\) 且权值为 \(-w\)

此时我们跑一遍 DFS 树求出只经过一条非树边的简单环,容易发现剩下的环都可以通过这些环的运算表示,那么根据 \(\gcd\) 的性质可以知道这样做并不影响最后的结果,于是我们就可以在 \(O(n+m)\) 的复杂度内解决这个问题了。

D CF1361E James and the Chase

\(\text{Link}\)

首先看到这个 \(20\%\) 容易想到这是一个随机化的题。先考虑怎样的点一定是好点,不难发现我们要满足以它为根时,DFS 树上没有横叉边和前向边。那么我们直接随机 \(100\) 次,然后判断这个点是不是好点,这样的话我们有 \(1-0.8^{100}\) 的概率找到一个好点,如果没有找到我们就直接认为不存在好点。

找到这个点的目的其实是为了求答案,我们以一个好点为根,这样 DFS 树上就只有树边和返祖边了。考虑怎样的点是好点,首先必须要满足的就是该节点子树内指向该点祖先的边不多于 \(1\) 条,原因显然。否则的话我们就记录下它子树中指向了哪个祖先(由于是强连通图所以每个点子树内一定有返祖边),只有当这个祖先是好点的时候这个点才可能是好点,原因依然显然。只要这两个条件都满足了的话这个点就是好点,否则就是坏点。

对于第一个条件,直接树上差分即可;对于第二个条件,我们对每个点记录其子树内指向的深度最浅的祖先然后判断即可。于是我们就可以在 \(O(100n)\) 的复杂度内解决这个问题。

E ARC161E Not Dyed by Majority (Cubic Graph)

\(\text{Link}\)

正解很有意思。我们直接随机一个答案,然后判断它是否合法。怎么判断可以考虑用 2-SAT,每个点有 WB 两种取值,根据每个点的最终答案连边即可,如果该情况无解那么就是最终答案。

为什么这是对的?我们发现对于不同的初始序列,得到的最终序列有很大一部分重复,而每一次重复会带来一个答案。考虑 \(1\) 号点相连的点 \(x,y,z\),并设它们相连的点为 \((1,x_0,x_1),(1,y_0,y_1),(1,z_0,z_1)\)。假如在初始序列中,\(x_0,x_1\)\(y_0,y_1\)\(z_0,z_1\) 的值分别相等,那么此时 \(1\) 号点的取值并不影响结果。容易发现满足前一个条件的序列总共有 \(2^{n-3}\) 种,这里面重复的序列有 \(2^{n-4}\) 个,也就是说我们的答案至少有 \(2^{n-4}\) 个,占到了总方案数的 \(\tfrac{1}{16}\),所以我们期望随机 \(O(1)\) 次后就应该可以得到一组解了。

F AGC056C 01 Balanced

\(\text{Link}\)

对于这个限制条件可以考虑差分约束。有一个 naive 的想法时直接设 \(s_i\) 是前缀和,那么限制条件就有两个:

  • \(s_r-s_{l-1} = \tfrac{r-l+1}{2}\)
  • \(0\le s_i-s_{i-1}\le 1\)

不过这样连边会有负边权,跑 SPFA 复杂度会炸。考虑另一种做法,将 \(0\) 换成 \(-1\),这样条件就变为:

  • \(s_r-s_{l-1}=0\)
  • \(|s_i-s_{i-1}|=1\)

第二个条件看上去不太好连边,不过实际上它在本题中等价为 \(|s_i-s_{i-1}|\le 1\);原因在于这样连边可以天然满足 \(s_i\ne s_{i-1}\),因为我们在跑最短路的时候所有 \(0\) 边连接的点的编号奇偶性相同,所以编号奇偶性不同的点的值奇偶性一定不同。

那么我们跑一遍最短路即可,这里由于边权为 \(0/1\) 所以可以用 0-1 BFS 解决,复杂度是 \(O(n)\) 的。注意我们跑完最短路后求出的是 \(s_i\) 的最大值,题目里要求字典序最小,所以实际上最后转化时要将 \(1\) 看成 \(0\)\(-1\) 看成 \(1\) 才是最小值。

G CF1163F Indecisive Taxi Fee

\(\text{Link}\)

先对整张图跑出一条最短路,接下来我们可以对询问的边在不在这条最短路上进行讨论:

  • 如果不在,那么答案要么是最短路,要么是经过这条边的最短路。后者可以从 \(1,n\) 各跑一遍最短路直接预处理求出。
  • 如果在,那么答案要么是经过这条边的最短路,要么是不经过这条边的最短路。前者的处理方式和上面一样,后者是比较难处理的。

所以现在的问题就是求出不经过最短路上某条边的最短路。既然不经过这条边那就要经过其它的边,所以我们从其余点的情况下手。考虑这样一个性质:从 \(1\) 走到 \(u\) 的最短路中,其一定有一个前缀是整张图最短路中 \(1\) 到某个点的路径,将最靠近 \(1\) 的这个点记作 \(l_u\);同理从 \(n\)\(u\) 也有这样一个点,记作 \(r_u\)

那么对于一条边 \((u,v)\) 来说,如果我们走 \(1\to u\to v\to n\),实际上是没有走过 \(l_u+1 \sim r_v\) 这些点上面的边的,也就是说如果我们将这些边删掉,这条路径的权值还是一个合法的答案。所以我们可以用线段树维护每一条边被删掉后能走出的路径的最小值,每次操作就是区间取 \(\min\)、单点查询。总复杂度是 \(O((n+m+q)\log n)\) 的。

H P3511 [POI 2010] MOS-Bridges

\(\text{Link}\)

首先显然二分答案然后转化为判定性问题,此时我们需要求出一张图上存不存在欧拉回路,不过这个图上既有有向边又有无向边,没有办法直接跑欧拉回路。我们考虑给每条无向边定向,使得它存在欧拉回路。那么定向后要满足的条件就是每个点的出入度相同。

考虑用网络流解决,对每条边 \(e_i\) 和点 \(v_i\) 考虑。先连边 \((S,e_i,1)\),然后对于每条边 \(e_i\),如果走向点 \(v\) 方向的权值合法,则连边 \((e_i,v,1)\)。最后我们需要保证每个点的入度恰好是其度数的一半,所以再连边 \((v_i,T,\tfrac{deg_{i}}{2})\)。这样的话跑一遍最大流,由于每一条边都要定向,所以只有源点向每一条边的流量都流满的话才说明合法,也就是说我们只需要判断最大流流量是不是 \(m\) 即可。

然后求出最小值后根据残量网络定向,跑一遍欧拉回路求出答案序列即可。复杂度能过。

I CF1458D Flip and Reverse

\(\text{Link}\)

发现这个题有一个要求是 \(0,1\) 出现次数相等,那么考虑和 F 题同样的思路,将 \(0\) 看作 \(-1\),则操作需要满足 \(s_{l-1}=s_r\)。我们连边 \((s_i,s_{i+1})\),会发现题目中所给的操作实际上就是把一个环边的方向、权值均取反后跑出的结果。然后你会发现这个转化很难蚌,因为你两个都取反后和没取实际上是没有区别的,于是我们就可以得出结论:图中任意一条欧拉路径都是可以转化出的字符串。

那么既然这样我们直接贪心选即可,先看能不能放 \(0\),能放的前提是放了之后回得来,如果回不来就得先把 \(1\) 放了再放 \(0\);否则的话直接放 \(0\) 就是最优的。贪心求一遍即可,复杂度 \(O(n)\)

J LOJ6271 「长乐集训 2017 Day10」生成树求和 加强版

\(\text{Link}\)

首先我们看到要对生成树权值求和,自然想到利用矩阵树定理进行求解。但是矩阵树定理适用于求边权之积的和的情况,与此题并不是很适配。考虑先进行一些转化。

我们发现一棵树的权值就是三进制不进位加法,首先由于不进位我们可以把每一位拆开考虑;而不进位加法则容易让我们想到 \(k\) 维 FWT。在本题中显然 \(k=3\),套用 \(3\) 维 FWT 不进位加法的做法,矩阵是 \(\begin{bmatrix}1&1&1\\1&\omega_3^1&\omega_3^2\\1&\omega_3^2&\omega_3^4\end{bmatrix}\),对于 \(i=0,1,2\) 求出边权 FWT 后的结果,则乘积就是答案 FWT 后结果。如此树的权值就被转化为了乘积,可以直接利用矩阵树定理求解。最后我们对答案做一次 IFWT 即可得出每种权值的树有多少种,累加答案即可。复杂度 \(O(n^3\log_3 V)\)

K P5470 [NOI2019] 序列

\(\text{Link}\)

首先这道题可以转化成一个简单的费用流模型,由于至少有 \(L\) 个下标相同,说明最多有 \(K-L\) 个下标不同,也就是说这一部分是自由的。建立源汇点 \(S,T\),连边 \((S,i,1,a_i),(j,T,1,b_j)\);同时在中间建两个点 \(u,v\) 表示自由流量,连边 \((u,v,K-L,0),(i,u,1,0),(v,j,1,0)\) 即可。

直接跑费用流的话复杂度太高,考虑利用模拟费用流优化。考虑直接模拟 EK 算法的过程,每次找到一条最短的增广路,然后把这条路径上的流量跑掉。考虑不同的增广路和它的操作本质:

  • \(S\to i\to j\to T\),这表示直接选一对下标相同的数字。
  • \(S\to i\to u\to v\to j\to T\),这表示选两边最大的两个数字,并且消耗 \(1\) 自由流量。
  • \(S\to i\to j\to v\to u\to i'\to j'\to T\),这时我们进行了三次退流,原本增广路是 \(S\to i'\to u\to v\to j\to T\),现在经过退流后变成了两条路径 \(S\to i\to j\to T,S\to i'\to j'\to T\)。也就是选择一个 \(a_i\) 未选但 \(b_i\) 已选、\(b_j\) 已选但 \(a_j\) 未选的两个数累加到答案中。同时我们会增加 \(1\) 自由流量。
  • \(S\to i\to j\to v\to j'\to T\),与上面类似,这表明原先有一个 \(i'\)\(j\) 匹配,经过退流后变成了 \(i'\)\(j'\) 匹配,\(i\)\(j\) 匹配。也就是选择一个 \(a_i\) 未选但 \(b_i\) 已选和任意一个 \(b_j\) 累加到答案中。
  • \(S\to i\to u\to i'\to j'\to T\),和上面一致,就是选择一个 \(b_i\) 未选但 \(a_i\) 已选和任意一个 \(a_j\) 累加到答案中。

显然只有这 \(5\) 种情况是最优的。于是我们只需要分别维护出当前未选的 \(a_i+b_i\)、当前未选的 \(a_i\)、当前未选的 \(b_i\)、当前未选 \(a_i\) 但已选 \(b_i\)\(a_i\)、当前未选 \(b_i\) 但已选 \(a_i\)\(b_i\) 的最大值即可进行上述模拟,单次增广在这几种情况中找最优解即可。复杂度是 \(O(n\log n)\) 的。

posted @ 2025-03-19 08:49  UKE_Automation  阅读(61)  评论(0)    收藏  举报