【A】图论
P7353 [2020-2021 集训队作业] Tom & Jerry
Tom 策略:只有站在割点才有威胁。如果你不能一步到达所有点双内的点,那么 Jerry 可以绕出去。否则可以将 Jerry 往子树内逼。
预处理所有子树的 dp。
对于 Tom 一开始不在割点,如果存在一个割点满足他的所有子树都是 Tom 赢那么走到那里就可以了。
P12077 [OOI 2025] Strong Connectivity Strikes Back
对于 DAG 边 \(u\to v\):只需要判定是否存在另外的 \(u\to v\) 的路径即可知道是否能删。
\(\color{Red}\mathtt \Gamma\)
CF730K Roads Orientation Problem
双极定向。
存在条件:缩点双后图是 \(s\to t\) 的一条链。
用圆方树的角度就是一定是 \(s,t\) 拉出来的链,方点可以挂圆点儿子,圆点不能有方点儿子。
在 dfs 生成树上跑,先在队列里插入 \((t,\downarrow)\)。
每次取队头,然后从 \(u\) 开始跳祖先,将祖先链都标成这种方向。
如果 \((u,v)\) 是一个返祖边,其中 \(u\) 是上端点,\(v\) 是我们队头节点的在 \(u\) 的同子树内节点,那么 \((u,v)\) 也要标成相同的方向,且 \(v\) 的祖先链方向要反向。那么插入 \((v,\mathrm{rev}(dir))\)。
P9394 白鹭兰
\(k=1\):双极定向,找一个拓扑序作为划分。
考虑双极定向的存在条件,拉出圆方树上 \(s\to t\) 的路径。
对于方点,可以逐个加入他的儿子,那么他儿子的子树是可以缩成一个点集的。
对于圆点,必须将他整个子树缩成一个点集,否则后缀就是不连通的。
暴力就是枚举 \(s,t\),然后 \(O(n)\) 构造双极定向。
考虑优化,枚举 \(s,t\) 的 LCA \(x\):
- 若 \(x\) 是圆点:选择其两个儿子,代价就是上面两个 \(s,t\) 的子树去掉后,整个树的大小。若 \(s,t\) 取前 2 大的子树,子树内代价一定 \(\le\) 前 2 大的子树大小。但是如果不去则一定会 \(\ge\) 前 2 大的子树大小,子树外还更大了,则一定更劣。
于是 \(s,t\) 必取前 \(2\) 大子树。 - 若 \(x\) 是方点:类似分析,代价变成去掉 \(s,t\) 子树后整个树的最大子树大小。还是应该取前 2 大的子树。
对于 \(s,t\) 确定在哪个子树内了,每次找一个儿子跳下去,直到跳到叶子。那么其实也是一直取最大的。
我们计算出 \(k_{\min}\) 然后双极定向构造方案。
AT_arc216_e [ARC216E] Swap or Reverse
首先发现如果把给定的二元组 \((x,y)\) 连边,那么同一个连通块里的两个点 \((u,v)\) 的操作都是可以造出来的。
令 \(c_i\) 表示 \(p_i\) 所在连通块的编号。发现无序二元组 \((c_i,c_{i+1})\) 在进行区间翻转或者交换两个位置后组成的集合是不变的,且这个是充要的。
那么从 \(c_1\) 开始跑字典序最小欧拉回路。
P9731 [CEOI 2023] Balance
\(S=2\):可以定向,然后入度和出度相差不超过 1,可以跑欧拉回路构造。
\(S=2^k\):分治,和上面一样跑。
P9139 [THUPC 2023 初赛] 喵了个喵 II
每个数只有两个:贪心划分,取第一次出现作为第一个子序列,存在两个数的出现区间有包含就无解。
那么考虑将四个同种数划分为两种新的数,划分方式只有 \((1,2),(3,4)\) 或者 \((1,3),(2,4)\),可以 2-SAT。使用 kosaraju 就不用显性建图。
P14792 [NERC 2025] Knit the Grid
用 \(a_{i,j}\) 表示 \((i,j)\) 被奇数还是偶数个环覆盖了。
那么对于 \((x_1,y_1),(x_2,y_2)\) 这两个格子之间的那个格线,他的存在性就是 \(a_{x_1,y_1}\oplus a_{x_2,y_2}\)。
故给出的网格就是 \(a_{x-1,y}\oplus a_{x+1,y}\oplus a_{x,y-1}\oplus a_{x,y+1}\)。
考虑一下 \(a\) 什么时候不合法,如果两个对角线上的格子都是相同的那么就是无解的。
即 \((a_{i,j}\oplus a_{i+1,j+1})\lor(a_{i+1,j}\oplus a_{i,j+1})=1\) 才是可行的。
可以变成 2-SAT 问题了。
AT_awtf2024_e Colorful Stamps
每个印章选择一个点染黑,每次盖章不能覆盖黑色格子。
发现不选角上的点会导致一些决策丢掉了,那么一定会选择角上作为黑色。
那么白色的位置每个时刻必须都是凸的,否则也会丢掉一些可能的决策。
考虑给前 \(k\) 个给出的矩形决策角,满足任意时刻白色都是凸的,剩下的印章我们按照从大往小选择容易构造。
考虑若染黑 \((x,y)\),令印章的左右边界是 \(l,r\),上下边界是 \(u,d\)。
那么 \((l-1,y),(r+1,y),(x,u-1),(x,d+1)\) 都必须被染黑。
否则由于当前染色矩形是极大的,所以一定存在一个边界外的是黑色的。
那么如果上述四个位置有一个是白色的就会导致染色后不是凸的。
然后发现行列是分离的可以 2-SAT。
线性规划
对偶:\(\max \mathbf c^{T} \mathbf x,A\mathbf x\le \mathbf b,\mathbf x\ge 0\Leftrightarrow \min \mathbf b^T\mathbf y,A^{T}\mathbf y\ge \mathbf c,\mathbf y\ge 0\)。
强对偶定理:\(\mathbf c^{T}\mathbf x=\mathbf b^T \mathbf y\)。
P6631 [ZJOI2020] 序列
设 \(\mathcal{S}=\{S_1,S_2,S_3,\cdots,S_k\}\),其中每个 \(S_i\) 是一种操作影响的下标集合。
设 \(x_k\) 表示 \(op_k\) 操作了几次,等于的限制可以拆成 \(\le,\ge\) 两个限制。
要求的是:\(\min \mathbf x,\sum_{i\in S_j} x_j\ge a_i,\sum_{i\in S_j}-x_j\ge -a_i,\mathbf x\ge 0\)。
对偶一下,\(\max \sum a_i(y_i-z_i),\sum_{i\in S_j} (y_i-z_i)\le 1,\mathbf y,\mathbf z\ge 0\)。
令 \(w_i=y_i-z_i,w_i\in \mathrm R\),则 \(\sum_{i\in S_j}w_i\le 1\),最大化 \(\max \sum a_iw_i\)。
先假设 \(w_i\) 取整数是优秀的。
然后这个限制其实就是一个最大子段和,可以使用 dp of dp:\(f_{i,x,y,z}\)。
思考一下发现 \(w_i\le -2\) 一定是因为不取这个值就会爆,那周围有至少 3 个 1,一定有一侧存在至少 2 个 1,那么就已经不合法了。故限制 \(w_i\in[-1,1]\) 就可以了。
CF2097F Lost Luggage
day \(i\) 到 day \(i+1\):每个点往前/中/后连边 \(a/b/c\) 的流量。跑最大流。
对偶得到最小割,考虑状压处理。可以记每个点是否与源点连通,逐位转移。\(O(nm2^n)\)。
CF1895G Two Characters, Two Colors
最小割建图:
若一个点是 1:\(s\to i\) 流量 \(r_i\),\(i\to t\) 流量 \(b_i\)。
若一个点是 0:\(s\to i\) 流量 \(b_i\),\(i\to t\) 流量 \(r_i\)。
对于一对逆序对 \((u,v)\):\(u\to v\) 流量 1,那么如果 \(u,v\) 同时选择 \(r_u,r_v\) 必须割掉 1 这条边。
这样 \(\sum_i r_i+b_i-\mathrm{maxflow}\) 就是最大的价值和。
发现可以先把 \(\min(r_i,b_i)\) 跑了,然后考虑流量是 1 边的贡献。
记 \(c_i=r_i-\min(r_i,b_i)\),发现 \(c_i\) 就是 1 点和 0 点的残量。
每次 0 点我们希望匹配 \(c_i\) 个 1 点的残量,那么一定是优先匹配较大的,这样最优。
那么可以平衡树维护前 \(k\) 大,拉出来打 tag 即可。
一份 FHQ 打 tag+有交合并代码:https://atcoder.jp/contests/abc427/submissions/70093842
CF1519F Chests and Keys
左部点是箱子右部点是钥匙,有限制就连边 inf,然后 B 的收益是 \(\sum a_i-\mathrm{maxflow}\)。注意到 \(\mathrm{maxflow}\le \sum a_i\),所以我们要求每个 \(a_i\) 都满流。
跑状压 dp。
P9070 [CTS2023] 琪露诺的符卡交换
对于 \(a_{i,j}=i\):直接转置矩阵。
那么你只需要重排行内的顺序,使得每列都是一个排列,然后做转置。
直接让 \(i\to a_{i,j}\),找 \(n\) 组完美匹配。
这是正则二分图,其实可以做到 \(O(n^2\log n)\)。
复习一下二分图匹配
bool dfs(int u)
{
for(auto v:e[u])
{
if(vis[v]) continue; vis[v]=1;
if(!bel[v]||dfs(bel[v])) return bel[v]=u,1;
}
return 0;
}
浙公网安备 33010602011771号