图论

目录

图论

之前讲过的有些题就没有再放上来,可以去前面的课件里面看看。

连通性问题

Tarjan 板子大家都会了。直接上例题。

CF1515G Phoenix and Odometers

给定一张 \(n\) 个点 \(m\) 条边的有向图,有边权,进行 \(q\) 次询问。每次询问给定三个参数 \(v,s,t\),你需要回答是否存在一条起点终点均为 \(v\) 的路径,满足 \(\text{路径长}+s\equiv 0\pmod t\)

\(2\leq n\le 2\times 10^5,1\leq m,q\le 2\times 10^5,0\leq s<t\leq 10^9\)\(1\leq\) 边权 \(\leq 10^9\)

显然只用在 \(v\) 的强连通分量里面考虑。注意到我们可以对图上所有的环进行任意复合。设环长为 \(c_1,c_2,\cdots\),根据裴蜀定理可以得到 \(\gcd(c_i,t)\) 倍数的长度。考虑我们只用找出一个生成树,计算所有含一条非树边的环即可。证明考虑线性基的那个经典证明(我不会)。

SP2878 KNIGHTS - Knights of the Round Table

\(n\) 个骑士经常举行圆桌会议。每次圆桌会议至少有 \(3\) 个骑士参加,且相互憎恨的骑士不能坐在圆桌的相邻位置。如果发生意见分歧,则需要举手表决,因此参加会议的骑士数目必须是大于 \(1\) 的奇数,以防止赞同和反对票一样多。知道骑士之间相互憎恨的 \(m\) 条关系后,请你帮忙统计有多少骑士参加不了任意一个会议。

\(1\leq n \leq 10^3,1\leq m\leq10^6\)

有一个结论:点双连通图中若包含一个奇环,则所有点都在至少一个简单奇环上。

证明:取出那个最初的奇环。上面的每一个点对之间都有一条长为偶数的路径和一条长为奇数的路径。考虑删去环后的连通块。它一定与环上至少两个点 \(x,y\) 相连,否则不满足点双性质。考虑连通块里的这条路径。如果长为奇数则可以与 \(x,y\) 间的偶长度路径连成奇环。否则与奇长度路径连。证毕。

我们建出补图,看每个点双有无奇环即可。

P4652 [CEOI2017] One-Way Streets

给定一张 \(n\) 个点 \(m\) 条边的无向图,现在想要把这张图定向。

\(p\) 个限制条件,每个条件形如 \((x_i,y_i)\),表示在新的有向图当中,\(x_i\) 要能够沿着一些边走到 \(y_i\)

现在请你求出,每条边的方向是否能够唯一确定。同时请给出这些能够唯一确定的边的方向。

数据保证有解。

\(1\le n,m,p\le 10^5\)

先求出边双,然后缩点。边双内的点不能确定。现在形成了一棵树。稍微树上差分一下就做完了。

P5234 [JSOI2012] 越狱老虎桥

给定一个 \(n\) 个点,\(m\) 条边的无向图,有边权。求出一条边 \(ans\),使得在原图上再加一条边,无论这条边加在哪,删除 \(ans\) 后,这个图不连通。最小化 \(ans\) 的边权。

先求出边双,然后缩点。显然边双内的边删不掉。现在考虑缩点后的树。加一条边相当于 ban 掉了一条链上的边。我们要求其他边的最大值。考虑从小到大枚举边,看看能不能 ban 掉。如果能加入当前的链就加入。暴力的复杂度是对的。

P7123 [NEERC2016] Indiana Jones and the Uniform Cave

交互题。有一张强连通的有向图,点数为 \(n\),每个结点的出度都等于 \(m\)。每个结点处有一个石头指向一条出边,同时有一个属于 \(\{0,1,2\}\) 的标记, 初始时每个结点的石头指向随机的一条出边,标记为 \(0\)。 你不知道图的结构,但你需要从某个点出发遍历每条边。每当经过一条边到达一个点后,你可以得知这个点的标记,然后选择修改标记和石头指向的出边,最后选择一条出边离开,但修改后的标记只能是 \(1\)\(2\)。一个点的所有出边可以看作是均匀地分布在一个圆周上,因此你在描述一条出边时只能通过“沿着之前石头指向的出边顺时针数的第 \(i\) 条”这样的形式。你只被允许通过 \(s\) 次边,注意你在任何时刻都是已知此前自己的所有决策的。

\(2\leq n,m\leq20,s=2\times 10^4\)

考虑我们模拟 dfs 算法的流程。我们记状态 \(0\) 为没有访问过的点,\(1\) 为当前点到根链上的点,\(2\) 为访问结束的点。每次 \(+1\) 遍历一个点的出边,如果状态是 \(0\) 则递归,若是 \(1\) 则发现走了返祖边,沿着树边走下来,把经过的点临时染成 \(2\),我们就知道走到了几级祖先。再走一遍把这些点染成 \(1\) 即可。若走到了 \(2\),则发现走了前向边。我们仍然一直走这个点现在的出边直到走到状态 \(1\),然后再使用树边走下来。为了确保我们可以这样走到状态 \(1\),我们仿照 Tarjan 记录 \(low\) 值,在离开一个点的时候,走到 \(low\) 最小的出边,也就是走能走到的祖先深度最浅的出边。然后再走到这个点的父亲。我们发现每一次遍历一条边最多要 \(2n\) 步,离开一个点最多要 \(2n\) 步,所以需要 \(2n^2m+2n^2\) 次操作,可以通过。

P6335 [COCI2007-2008#1] STAZA

给出一个连通的无向边仙人掌。你的任务是找到满足以下两个约束条件的最长路线:

  • 路线可以从任何城市开始,但必须在城市 \(1\) 结束。

  • 这条路线可以多次访问同一个城市,但不能经过同一条道路超过一次。

请你输出最长的路线的长度。

\(2\le n\le 10^4,1\le m\le 2n-2\)

显然转成从 \(1\) 开始。考虑在仙人掌的环上 DP。设 \(f_i\) 表示从 \(i\) 往下走回到 \(i\) 的最长距离。\(g_i\) 表示从 \(i\) 往下走不用回到 \(i\) 的最长距离。设 \(w_i=g_i-f_i\)。分别考虑:非环边只能对 \(g\) 有贡献,即 \(w=\max(w,g_j+1)\)(走完 \(f_i\) 再往下多走 \(g_j+1\))。环边则考虑 \(f_i\) 加上环上所有 \(f_j\) 加环长。\(g_i\) 肯定是走一半的环(走路径上的 \(f\))然后走 \(g_j\),从两个方向分别计算最大值即可。

P4320 道路相遇

给出一个 \(n\) 个点 \(m\) 条边的连通无向图,\(q\) 次询问每次给出 \(u,v\) 询问从 \(u\)\(v\) 的所有简单路径都会经过的点有几个。

\(1\leq n\leq 5 \times 10^5, 1\leq q\leq 5\times 10^5, 1\leq m\leq \min(\frac{n(n-1)}{2}, 10^6)\)

圆方树板子题。建出圆方树后我们发现,答案就是圆方树上 \(u,v\) 之间的圆点个数(相当于是路径上的割点个数)。将圆点赋成 \(1\),方点赋成 \(0\),直接计算即可。

P10517 国土规划

给出一个 \(n\) 个点 \(m\) 条边的连通无向图。每个点有权值 \(0/1\)\(q\) 次操作每次 flip 一个点的权值或者询问:有多少个权值为 \(0\) 的点,满足删去它之后,所有权值为 \(1\) 的点仍然连通。

\(2 \le n \le 10^5,n-1\le m \le 2 \times 10^5,1 \le q \le 2 \times 10^5\)

考虑算出删去它之后,所有权值为 \(1\) 的点不连通的点数,也就是路径上必须经过的点个数。和上一题一样建出圆方树,考虑按 dfs 序排序维护权值为 \(1\) 的点,答案就是相邻两个元素路径答案之和的一半。使用 set 维护即可。

P10829 [COTS 2023] 三元图 Graf

对于非负整数 \(k\),我们递归地给出 \(k-{}\)三元图的定义。

  • \(k-{}\)三元图是无向图。
  • 对于 \(k=0\)\(k-{}\)三元图 是一个仅包含 \(1\) 个节点和 \(0\) 条边的图。
  • 对于 \(k\gt 0\)\(k-{}\)三元图由三个 \((k-1)-{}\)三元图组合而成。具体地说,在这三个 \((k-1)-{}\)三元图中各选择一个节点,然后在这三个节点之间两两连边,得到的就是 \(k-{}\)三元图。

下图展示了一张 \(3-{}\)三元图。

给定 \(n\) 个点 \(m\) 条边的无向图 \(G\),判断它是否是 \(k-{}\)三元图。

\(1\le n\le 2\times 10^5,0\le m\le 3\times 10^5\)

考虑建出圆方树。我们发现关键性质:原图中每一个三元环都形成了一个点双,而且一个三元环向下一级结构连边。发现最高一级三元环的方点是整个树的重心。所以条件就是:所有点双的大小为 \(3\),并且圆方树的点分树是完美三叉树。

P8456 「SWTR-8」地地铁铁

给定一张 \(n\) 个点,\(m\) 条边的无向连通图。每条边标有 Dd

计算无序点对 \((x, y)\) 的数量,使得 \(x, y\) 之间存在同时出现 Dd 的简单路径。

\(2\leq n \leq 4\times 10 ^ 5,n - 1\leq m\leq 10 ^ 6\)

考虑建出圆方树。我们设方点的颜色集合为它所在点双内边的颜色的并。对于不在一个点双内的点对,它们在圆方树上的路径经过了不小于 \(2\) 个方点。我们只需要这些方点中存在颜色集合大小为 \(2\) 的点即可(这一个点双内走与其他点双不同的颜色)。这部分可以树形 DP 解决。对于在同一个点双内的点对,第一个条件是这个点双两种颜色都存在。但是存在特例:对于 1 2 D 2 3 d 3 1 d 这种情况,\(1,2\) 两点间只有 \(d\) 路径或 \(D\) 路径。容易发现这样的点在点双内最多有一对,存在这样的点对当且仅当存在恰好两个点使得它们的所有邻边有两种颜色。求点双时求一下即可。

P10674 【MX-S1-T3】电动力学

给定一张包含 \(n\) 个点 \(m\) 条边的简单无向连通图。

你需要求出有多少集合对 \(S,T\subseteq \{1,2,\dots,n\}\),满足对于任意的 \(i\in S\),要么 \(i\)\(\in T\),要么存在 \(x,y\in T\)\(x\neq y\)),满足存在一条从 \(x\)\(y\) 的简单路径经过 \(i\)

注意,集合对 \(S,T\) 可以为空集。

输出答案对 \(998244353\) 取模后的结果。

\(2\le n\le 5\times 10^5,n-1\le m\le 10^6\)

枚举 \(T\),设 \(c\) 为圆方树上 \(T\) 的虚树代表的点集大小,贡献就是 \(2^c\)。我们将圆方树上方点权值设为点双点数减一,圆点权值设为 \(0\)\(c\) 就是虚树上方点权值和加一。然后考虑在圆方树上 DP,在根统计贡献。设 \(f_u\) 表示 \(u\) 子树的虚树贡献和。对于答案,在圆点时,可以选两个或以上子树,然后这个点选或不选都行。也可以选 \(0/1\) 个子树,然后选这个点。方点时,不能单独选这个点,只能选两个或以上子树。\(f\) 类似讨论转移即可。

P11220 【MX-S4-T4】「yyOI R2」youyou 的三进制数

现在有 \(0 \sim n\)\(n + 1\) 个数。
定义 \((x)_{3}\) 表示十进制数 \(x\) 的三进制形式。如果没有特别强调,那么这些数均为十进制形式。

一个非负整数序列 \(a\) 被称为“完美的”,当且仅当:

  • \(a_i \in [0,n]\)
  • 不存在 \(i,j\)\(1 \le i <j \le p\)),使得 \(a_i = a_j\)
  • 对于任意 \(1 \le i < n\)\(a_i\)\(a_{i+1}\) 至少满足以下四个条件中的一个:
    1. \((a_i)_3\) 去掉最后一位,恰好等于 \((a_{i+1})_3\)(若只有一位,则去掉后的数字为 \(0\))。
    2. \((a_i)_3\) 末尾添上某一位 \(t(0 \le t \le 2)\),恰好等于 \((a_{i+1})_3\)(若 \(a_i = 0\),则添加后舍去前置 \(0\))。
    3. \(a_i \le w\)\((a_i)_3\) 的末尾不是 \(0\),且将末尾的一位数字移到开头与 \((a_{i + 1})_3\) 相等。
    4. \((a_i)_3\) 长度 \(\ge 2\),且 \((a_i)_3\) 次高位非零时,将 \((a_i)_3\) 开头的一位数字移到末尾,形成的数的十进制值 \(\le w\),且恰好等于 \((a_{i+1})_3\)

定义十进制三元组 \((x,y,z)\) 是好的,当且仅当:

  • \(0 \le x,y,z \le n\)\(x \neq y\)
  • 存在至少一个“完美的”序列 \(b\),使得十进制下有 \(b_1=x\)\(b_s = y\)。其中 \(s\) 为序列长度。
  • 存在至少一个“完美的”序列 \(c\),使得十进制下有 \(c_1=z\)。同时,对于上述任意的 \(b\),均有恰好一对 \((i, j)\),满足 \(1 \le i \le |b|\)\(1 \le j \le |c|\),使得 \(b_i = c_j\)

对于每一个 \(0 \le z \le n\),求能构成“好的”三元组 \((x,y,z)\) 的有序对 \((x,y)\) 的个数。

\(1\le n \le 3 \times 10^5,0 \le w \le n\)

我们发现对于这 \(4\) 个性质,前两个互逆,后两个互逆。因此我们把符合条件的数对连双向边。现在转化为,对于一个 \(z\),有多少个点对 \((x,y)\),满足存在一条从 \(z\) 出发的简单路径与 \((x,y)\) 间的所有简单路径的交点个数都为 \(1\)

我们有结论:这个交点对所有 \((x,y)\) 间的简单路径都是一样的。证明考虑如果交点有两个点 \(i,j\),路径为 \(z\to i\to j \to ed,x\to i\to y,x\to j \to y\),则一定存在 \(x\to i\to j\to y\),不符合条件。

现在我们考虑建出圆方树,一个 \((x,y)\) 有贡献的 \(z\) 就是:\((x,y)\) 链上所有的圆点,以及圆点不包含 \(x\)\(y\) 的子树。

考虑怎么计算。方点没有贡献。圆点的任意两个子树 \(x,y\) 对子树外的所有点有贡献 \(2\times siz_x\times siz_y\)。树上差分即可。

AT_xmascon22_h Happy Game

直接看 H_W_Y 博客吧。

P9167 [省选联考 2023] 城市建造

给定一张 \(n\) 个点 \(m\) 条边的无向连通图 \(G = (V, E)\),询问有多少该图的子图 \(G' = (V', E')\),满足 \(E' \ne \varnothing\)\(G - E'\) 中恰好有 \(|V'|\) 个连通块,且任意两个连通块大小之差不超过 \(k\),保证 \(0 \le k \le 1\),请输出答案对 \(998244353\) 取模的结果。

\(3 \le n \le 10^5,n - 1 \le m \le 2 \times 10^5,0 \le k \le 1\)

考虑建出圆方树。因为删的边与连通块个数相同,所以选择的点集在每个连通块内恰有一个点。考虑若选了一个点双内的两个点,那么所有点都要被选,否则不满足每个连通块有一个点。我们说选了一个方点代表选了点双内的所有点,那么我们有结论:

  • 选的方点形成一个连通块(类似上面可证)。

  • 圆方树上若是方点作为重心,则它一定要被选,证明考虑若不选它,那么这两个连通块的差一定大于 \(1\)

结合上面两个结论可以发现,若选了方点 \(u\),则 \(u\) 的祖先全部要选。

把重心作为根,我们考虑 DP。设 \(f_u\) 表示 \(u\) 子树选方点的方案数。设 \(siz_u\) 表示子树中圆点个数。注意圆方树上都是圆点连方点。

  • \(k=0\)

    枚举连通块大小 \(x\)

    • \(siz_u<x\) 没有方案。否则:

    • \(u\) 为方点:\(f_u=\prod\limits_{v\in son_u}f_v\)

    • \(u\) 为圆点:

      • \(\left(\sum\limits_{v\in son_u,siz_v<x}siz_v\right)+1=x\)\(f_u=\prod\limits_{v\in son_u,siz_v\ge x}f_v\)

      • 否则没有方案。

  • \(k=1\)

    枚举连通块大小为 \([x,x+1]\)

    • \(siz_u<x\) 没有方案。否则:

    • \(u\) 为方点:\(f_u=\prod\limits_{v\in son_u}f_v\)

    • \(u\) 为圆点:可以保留一个 \(siz_v=x\) 的子树,与这个点合成 \(x+1\),但是要保证 \(\sum\limits_{v\in son_u,siz_v<x}siz_v=0\)。如果存在 \(siz_v=x,f_v=0\) 的,可以保留一个,大于一个没有方案。如果不存在,保留任意一个 \(siz_v=x\) 的即可(当然也可以不保留)。设 \(cnt_1=\sum\limits_{v\in son_u}[siz_v=x],cnt_2=\sum\limits_{v\in son_u}[siz_v=x\land f_v=0]\),即:

      • \(\sum\limits_{v\in son_u,siz_v<x}siz_v=0,cnt_2=1\)\(f_u=f_u+\prod\limits_{v\in son_u,siz_v> x}f_v\)

      • \(\sum\limits_{v\in son_u,siz_v<x}siz_v=0,cnt_2=0\)\(f_u=f_u+cnt_1\times \prod\limits_{v\in son_u,siz_v> x}f_v\)

      • \(\left(\sum\limits_{v\in son_u,siz_v<x}siz_v\right)+1\in [x,x+1]\)\(f_u=f_u+\prod\limits_{v\in son_u,siz_v\ge x}f_v\)

      • 否则没有方案。

考虑枚举连通块是 \(O(\sqrt{n})\) 的,总复杂度 \(O(n\sqrt{n})\)

P7353 [2020-2021 集训队作业] Tom & Jerry

给定一张包含 \(n\) 个顶点和 \(m\) 条边的无向连通图,Tom 和 Jerry 在图上进行了 \(q\) 次追逐游戏。

在第 \(i\) 次游戏中,Tom 一开始位于顶点 \(a_i\),而 Jerry 一开始位于顶点 \(b_i\)(双方任何时候都知道自己和对方的位置),追逐规则如下:

  • Jerry 和 Tom 交替行动,Jerry 先行动。

  • Jerry 每次行动可以通过无向图中的任意多条边(可以选择不移动),但是在移动过程中不能经过 Tom 当前所在的结点,否则就会被抓住。

  • Tom 每次行动只能通过无向图中的至多一条边(可以选择不移动)。

  • 如果 Tom 在一次行动后到达了 Jerry 的位置,那么 Tom 胜利。

Tom 尽量想要胜利,而 Jerry 会尽量阻止 Tom 胜利。

现在你需要对于每一局游戏,求出 Tom 是否一定能在有限次行动内获胜。

\(1\leq n,m,q\leq 10^5\)

我们考虑刻画 Tom 的策略。感性理解可以发现 Tom 会限制 Jerry 的范围最后抓住他。我们先建出圆方树,把 \(a\) 作为根。考虑 Jerry 最先可以在 \(a\) 的一个子树里面任意移动。Tom 肯定会向这个子树里面走。设走了一步在 \(u\),注意到 Jerry 可以在子树的任意位置。我们发现如果 Tom 一步走不到在 \(u\) 点双内且在 \(u\) 子树内所有点,Jerry 就可以走到这个点然后等 Tom 走了之后直接出去,否则 Tom 就可以缩小空间。但是注意到 Jerry 走出去之后不一定就赢了。如果一个点不管 Jerry 在子树内子树外都可以让 Tom 获胜,那所有答案就是 Yes。这样就充分了。我们进行换根 DP,讨论 \(b\) 的位置即可。

其实还有耳分解这个东西,但是我声称用处不大,我也不是很会。要看的可以看 UOB 博客

环计数

三元环计数

首先给所有边定向。我们规定从度数小的点指向度数大的点,度数相同就从编号小的点指向编号大的点。考虑我们定义了一个偏序关系,那么此时此图是一张 DAG。

枚举 \(u\)\(u\) 指向的点 \(v\),再在 \(v\) 指向的点中枚举 \(w\),检验 \(w\) 是否与 \(u\) 相连即可。时间复杂度为 \(O(m\sqrt{m})\)。证明:记 \(deg_x\)\(x\) 的出边个数,若 \(deg_v<\sqrt{m}\) 则显然复杂度正确。否则有 \(deg_u\ge deg_v\ge \sqrt{m}\)\(u\) 的个数 \(\leq \sqrt{m}\),即证。

四元环计数

讨论环 \((A,B,C,D)\) 的形态:

  • \(A\to B,B\to C,A\to D,D \to C\)
  • \(A\to B,B\to C,C\to D,A \to D\)
  • \(A\to B,A\to D,C\to B,C \to D\)

和三元环一样枚举即可。

例题

板子:P1989 无向图三元环计数

P3547 [POI2013] CEN-Price List

给定一个 \(n\) 个点 \(m\) 条边的无向图,边权均为 \(a\)

现在将原来图中满足最短路等于 \(2a\) 所有的点对 \((x,y)\) 之间加一条长度为 \(b\) 的无向边。

给定 \(k\),求点 \(k\) 到所有点的最短路是多少。

\(2\le n\le 10^5,1\le m\le 10^5\)

考虑边权有三种情况:

  • \(2a<b\),就是原来的最短路。

  • \(2a>b\),设原来是 \(wa\)

    • 可以是前 \(\left\lfloor\dfrac{w}{2}\right\rfloor\) 条边为 \(b\),最后走一个 \(a\)

    • 可以是多走几条边,但是全是 \(b\)

考虑最后一种情况。使用 0/1 bfs,我们相当于是要一次走两步。我们考虑第二条边如果被访问了,它一定已经没用了。我们将它删去即可。这样只有三元环不能有这样的松弛,其他边都只访问一遍。而三元环个数为 \(O(m\sqrt{m})\),总复杂度就是这个。

2-SAT

算法大家都会了。

2-SAT 常常是建出模型后与优化建图结合。某些特殊模型可以多项式时间求出方案数。

Meatherm 的课件里面有一些题,这里有另一些题。

例题

P7477 「C.E.L.U-02」划分可重集

给你一个长度为 \(n\) 的数列 \(v\),请你将其划分成两个可重集 \(a\)\(b\)

一个数 \(v_i\) 可以被划分进 \(a\) 当且仅当 \(j<i \land v_j\le v_i-k\)\(v_j\) 都没有被划分进 \(a\)。一个数 \(v_i\) 可以被划分进 \(b\) 当且仅当 \(j<i\land v_j\ge v_i+k\)\(v_j\) 都没有被划分进 \(b\)

同时给出了 \(m\) 组关系,每组关系代表 \(u\)\(v\) 不能划分进同一个可重集里。求能使划分成功的最小的 \(k\)。如果不存在合法划分,请输出 -1

\(1\leq n,m\le 2\times 10^4,0\leq k,v_i\le 10^9\)

显然先二分,然后 2-SAT 判定。使用你喜欢的优化建图方法即可。

CF1903F Babysitting

给你一个 \(n\) 个点 \(m\) 条边的无向图,你需要求出一个点覆盖使得选出点编号之间的最小差距最大化。

形式化的,如果你选出的点集为 \(a_1,a_2,\dots,a_k (a_1<a_2<\dots<a_k)\),那么最小差距即为 \(\min \limits_{i=1}^{k-1}{(a_{i+1}-a_i)}\),特别的,当 \(k=1\) 时最小差距为 \(n\)

输出这个最大值。

\(1 \le n \le 10^{5}, 1 \le m \le 2 \times 10^{5}\)

二分 \(k\),考虑限制就是:一条边两个点必须选一个,差大于 \(k\) 的不能同时选。2-SAT 判定,使用你喜欢的优化建图方法即可。

P5297 [北京省选集训2019] 完美塔防

游戏的棋盘是一个 \(n \times m\) 的网格,每个格子上会有以下类型物件:

  1. A 型炮台:会向上下两个方向同时发射激光,符号为 |
  2. B 型炮台:会向左右两个方向同时发射激光,符号为 -
  3. 空地:激光穿过该物件会保持方向前进,符号为 .
  4. 障碍:激光到达该物件会消失,符号为 #
  5. 正反射镜:激光到达该物件后,会依物理定律改变方向,但仍继续前进,符号为 \
  6. 副反射镜:激光到达该物件后,会依物理定律改变方向,但仍继续前进,符号为 /

注意激光之间可以互相穿过,但如果激光射出网格边界,也会消失。
小 N 是一个强迫症玩家,他想让每一处空地都会被至少一束激光打到,但不能让激光攻击到自己的炮台以致损坏。
小 N 可以将任意多的 A 型炮台改造成 B 型炮台,也可以把任意多的 B 型炮台改造成 A 型炮台。
你可以告诉他能否通过这些改造实现他的目标吗?你需要构造方案。

\(1\le n,m \le 50\)

考虑一个炮台有两个状态,记为 \(0/1\)。若某个方向可以打到其他炮台就不能为这个方向。对每个空地考虑。因为光路可逆,所以每个空地在横向和竖向上最多会被一个炮台打到,也就是对这两个有限制。2-SAT 即可。

CF1215F Radio Stations

\(p\) 个电站,需要选择一种电站序列使其满足:

  • \(n\)\((x,y)\)\(x\) 电站或 \(y\) 电站中至少有一个。

  • \(m\)\((x,y)\)\(x\) 电站或 \(y\) 电站中最多有一个。

  • \(i\) 个电站有两个参数 \(l_i\)\(r_i\) \((1\leq l_i\leq r_i\leq M)\),表示其覆盖的区间为 \([l_i,r_i]\)。若选定一个电站序列,序列中所有电站覆盖区间的交集不能为空。要求若求得一种合法电站序列,输出交集中任意一个点。

$ 2 \le n, p, M, m \le 4 \times 10^5 $。

电站间的限制是简单的。考虑交集的限制。设交集中有一个点 \(f\),我们建 \(2(M+1)\) 个点表示 \(f\leq i(0\leq i\leq M)\) 是否满足。有基本限制:\(f\leq i+1\Rightarrow f\leq i,f\ge i+1\Rightarrow f\ge i\)。对于每个电站有 \(f\leq l_i-1\) 不能选,\(f\leq r_i\) 可以选。注意 \(f\ne 0\)

CF587D Duff in Mafia

给定一张 \(n\) 个点 \(m\) 条边的无向图,每条边有一个颜色 \(c\) 和权值 \(t\)

你要选出一些边,使得它们两两不共端点,同时剩下的边每种颜色两两不共端点。

同时,你要最小化选出的边的最大权值。

\(2\leq n \le 5 \times 10^4,1\leq m \le 5 \times 10^4\)

每条边有两个状态:第一次选或第二次选。考虑二分答案 \(ans\)\(>ans\) 的边第一次不能选。同一个顶点处两条边不能第一次同时选,同一个颜色同一个顶点处两条边不能第二次同时选,后面两个限制可以把边拆成在两个顶点处的限制然后前缀优化建图即可。

P5332 [JSOI2019] 精准预测

目前,火星小镇上有 \(n\) 个居民(编号 \(1,2,\cdots,n\))。我们预测出这些居民在接下来 \(T\) 个时刻(编号 \(1,2,\cdots,T\))的生死情况共 \(m\) 条,每条预测都是如下两种形式之一:

  • \(0\) \(t\) \(x\) \(y\):在 \(t\) 时刻,如果 \(x\) 是死亡状态,那么在 \(t+1\) 时刻,\(y\) 是死亡状态。(注意,当 \(x\)\(t\) 时刻是生存状态时,该预测也被认为是正确的)。

  • \(1\) \(t\) \(x\) \(y\):在 \(t\) 时刻,如果 \(x\) 是生存状态,那么在 \(t\) 时刻,\(y\) 是死亡状态。(注意,当 \(x\)\(t\) 时刻是死亡状态时,该预测也被认为是正确的)。

注意本题是对某个时刻进行生死状态的预测,如果某个人在 \(t\) 时刻是生存状态,在 \(t+1\) 时刻是死亡状态,你可以认为是在 \(t\)\(t+1\) 这段时间内发生了某个事件导致其死亡。

具体来说,假设预测全部正确,在此基础上,希望为每个居民 \(k\) 分别计算有多少人有可能和他一起活到第 \(T+1\) 时刻,换言之,希望为每个 \(k\) 计算 \(\sum\limits_{1 \leq i \leq n,i \neq k} \operatorname{Live}(k,i)\),其中 \(\operatorname{Live}(i,j)=1\) 表示编号为 \(i\)\(j\) 的火星人有可能同时在第 \(T+1\) 时刻处于生存状态,否则 \(\operatorname{Live}(i,j)=0\)

注意火星人是不能够复活的。一个火星人可能在时刻 \(1\) 就处于死亡状态,也有可能有预测未覆盖的死亡情况发生(火星人在任何时候都可能死亡,但任意时刻观察到火星人的状态要么活着,要么死亡)。最后,注意到 \(\operatorname{Live}\) 是为每一对火星人分别独立计算的,因此 \(\operatorname{Live}(x,y)=1,\operatorname{Live}(y,z)=1\) 并不意味着 \(\operatorname{Live}(x,z)=1\)

\(1\leq T\leq 10^6,1\leq n\leq 5\times 10^4,0\leq m\leq 10^5\)

我们先建出 \(2(T+1)n\) 个点,表示每个人在每个时刻的生死状态。对于基本限制有:\(t+1\) 时刻 \(x\) 活着那么 \(t\) 时刻 \(x\) 活着;\(t\) 时刻 \(x\) 死了那么 \(t+1\) 时刻 \(x\) 死了。限制一为:\(t\) 时刻 \(x\) 死了那么 \(t+1\) 时刻 \(y\) 死了;\(t+1\) 时刻 \(y\) 活着那么 \(t\) 时刻 \(x\) 活着。限制二为:\(t\) 时刻 \(x\) 活着那么 \(t\) 时刻 \(y\) 死了;\(t\) 时刻 \(y\) 活着那么 \(t\) 时刻 \(x\) 死了。我们发现只有后两个限制中存在的点有特殊边,因此基本限制可以只在这些点中间连,个数降到了 \(O(n+m)\)。考虑答案是什么。显然就是 \(T+1\) 时刻一个人活着能导出 \(T+1\) 时刻某些人死了,剩下的人就可能和他一起活着,也就是判断可达性。注意到图中活着只能连时刻不早于它的活着或者连死了,死了只能连时刻不晚于它的死了,也就是说原图就是一个 DAG,不需要缩点。我们使用 bitset 即可(需要分块 bitset)。

P6898 [ICPC2014 WF] Metal Processing Plant

\(n\) 个货物分割为两组。

每对货物 \(i,j\) 给出一个 \(d_{i,j}\),对于子集 \(S\)\(D(S)\) 定义为 \(\max\limits_{i,j\in S,i\ne j}d_{i,j}\)

你需要将货物分成 \(A\)\(B\) 两部分,使 \(D(A)+D(B)\) 最小。输出这个最小值。

\(1 \le n \le 200,0\leq d_{i,j}\leq 10^9\)

\(D(A)>D(B)\)。考虑如果我们枚举 \(D(A)\),那么 \(D(B)\) 的可行性单调。可以使用 2-SAT 判定(\(>D(A)\) 无法同时在一个集合里,\(\leq D(A),>D(B)\) 无法同时在 \(B\) 中)。可以双指针做到 \(O(n^4)\)

考虑一下所有 \(>D(A)\) 的边。相当于对端点有染色限制。我们从大到小枚举权值为 \(D(A)\) 的边是哪一个,维护一个 \(>D(A)\) 的边集。若加入这条边形成了偶环,则现在这条边不能作为 \(D(A)\)(因为两个端点颜色必须不同)。若形成了奇环,则这条边可以作为 \(D(A)\),但是还没加入的边不能再作为 \(D(A)\),直接 break 即可。对于不会成环的 \(O(n)\) 条边,直接二分 \(B\) 即可。复杂度 \(O(n^3\log n)\)

竞赛图

定义

竞赛图是一个简单有向图,满足任意两点之间都有且仅有一条边。

性质

性质 1:竞赛图有哈密顿路。

性质 1 证明:考虑归纳。设 \(n-1\) 个点的竞赛图的哈密顿路为 \(1\to 2\to \cdots\to n-1\)。考虑:

  • 若有 \(n \to 1\),将 \(n\) 放到最开头。
  • 若有 \(n-1 \to n\),将 \(n\) 放到最后。
  • 否则有 \(1\to n,n\to n-1\),边的方向不同,一定可以找到一个 \(x\) 使得 \(x\to n,n\to x+1\)\(n\) 放在 \(x,x+1\) 中间即可。

性质 2:强连通的竞赛图有哈密顿回路。

性质 2 证明:构造性证明。先构造出一个哈密顿路。设为 \(1\to 2\to \cdots\to n\)。设最大的一个 \(t\) 使得 \(t\to 1\)。则对于所有不在环 \(1\to 2\to \cdots\to t\to 1\) 上的点 \(x\),有 \(1\to x\)。显然有至少一个 \(x\) 存在 \(x\to y\),其中 \(y\) 是环上的点,因为图是强连通的。类似性质 1 证明将 \(x\) 加入环,直到所有点都在哈密顿回路中。

性质 3:竞赛图缩点后形成一条链。

性质 3 证明:对于不同两个强连通分量中的点 \(x,y\),由于一定存在 \(x\to y\)\(y\to x\),因此 \(x\) 可达 \(y\)\(y\) 可达 \(x\) 。所以强连通分量间的可达关系形成全序,也就是缩点后形成一条链。

性质 4(Landau 定理):设竞赛图中所有点按照出度从小到大排序为\(p_1,p_2\cdots,p_n\)\(p_i\) 的出度为 \(d_i\),则对于每个 \(1\leq k\leq n\),有 \(\sum\limits_{i=1}^kd_i\ge {k\choose 2}\)

性质 4 证明:仅考虑前 \(k\) 个点的导出子图,共有 \({k\choose 2}\) 条边,这已经为 \(\sum\limits_{i=1}^kd_i\) 贡献了 \({k\choose 2}\) 条边。结论成立。

性质 4 推论:每个强连通分量是排列 \(p\) 中的一个连续段,靠右的强连通分量可达靠左的强连通分量,且 \(p_k\) 是一个强连通分量的右端点当且仅当 \(\sum\limits_{i=1}^kd_i= {k\choose 2}\)

性质 4 推论证明:

\(x,y\) 属于不同强连通分量,且 \(x\) 可达 \(y\)。那么对于所有 \(y\) 的出边 \(y\to z\),显然一定存在边 \(x\to z\),在此基础上 \(x\) 至少还多一条出边 \(x\to y\),因此 \(x\) 的出度大于 \(y\) 的出度。这说明每个强连通分量确实是排列 \(p\) 中连续的一段,且靠右的强连通分量可达靠左的强连通分量。

后面那个结论是好证的。充分必要各证一下即可。

例题

HDU 5503 EarthCup

\(n\) 支球队参加比赛,每两支球队都会比一场,赢得一分,输得零分,给出 \(n\) 支球队最终得分,判断是否存在合法方案满足该得分情况。

\(1\leq n\leq 5\times 10^4\)

使用 Landau 定理判定即可。

P3561 [POI2017] Turysta

给出一个 \(n\) 个点竞赛图。

对于每个点 \(v\),求出从 \(v\) 出发的一条经过点数最多的简单路径。

\(2\le n\le 2 \times 10^3\)

先缩点,显然一个点的答案就是它能到的强连通分量的哈密顿回路拼起来。

QOJ #5407. 基础图论练习题

给定 \(n\) 个点的竞赛图,对于每条边求翻转这条边后图的强连通分量个数。

\(1\leq n\leq 5000\)

考虑使用 Landau 定理。我们维护排序后的出度序列,维护 \(\sum\limits_{i=1}^kd_i- {k\choose 2}\),这样一次相当于单点修改,询问全局 \(0\) 的个数。直接做即可。

BZOJ 5219 最长路径

没地方交 /kx

计算有多少个 \(n\) 个点的竞赛图,使得从 \(1\) 号点出发的最长简单路径经过点数恰好为 \(k\)。对 \(P\) 取模。

\(1\leq n \leq 2000,2\leq P\leq 10^9\)

我们考虑 DP。设 \(f_{i,j}\) 表示 \(i\) 个点最长路径为 \(j\) 的方案数。考虑我们有:

  • \(f_{i,0}=2^{\dfrac{(n-1)(n-2)}{2}}\),因为只需保证边是 \(i\to 1\)
  • \(f_{i,j}=f_{j,j}\times {i-1\choose j-1}\times2^{\dfrac{(i-j)(i-j-1)}{2}}(j<i)\)。我们枚举不在路径上的边。它们要向所有在路径上的点连边。内部随便连。
  • \(f_{i,i}=2^{\dfrac{i(i-1)}{2}}-\sum\limits_{j=0}^{i-1}f_{i,j}\),稍微容斥一手。

CF913F Strongly Connected Tournament

\(n\) 个人进行比赛。

  1. 起初,每个人与其他每一个人比赛。
  2. 在比赛之后,建立一个竞赛图:一对人之间比赛的胜利者是边的起点,输了的人是终点。
  3. 然后对原图进行缩点,之后这张图变成了由原图的强连通分量组成的一条链。
  4. 对每个强连通分量继续做上述操作,直到每个强连通分量的大小为 \(1\)

我们知道 \(i\) 能赢运动员 \(j(i<j)\) 的概率为 \(p\)。求出比赛总场数的期望值,对 \(998244353\) 取模。

\(2\leq n\leq 2000\)

\(i\) 个人的期望场数为 \(ans_i\)。我们枚举最后一个强连通分量的点数,有:

\[ans_i=\sum_{j=1}^{i}c_jd_{i,j}\left(\dfrac{j(j-1)}{2}+j(i-j)+ans_j+ans_{i-j}\right) \]

其中 \(c_i\) 表示 \(i\) 个人形成强连通分量的概率,\(d_{i,j}\) 表示 \(i\) 个人其中 \(j\) 个人输掉了其他 \(i-j\) 人的概率。后面就是加上分出来的答案和这次的边数。我们发现有自己转移到自己的情况,我们把这一项拉出来移项即可。

对于 \(c_i\),考虑就是不能缩点之后有多个点,就是:

\[c_i=1-\sum_{j=1}^{i-1}c_jd_{i,j} \]

对于 \(d_{i,j}\),分讨新点 \(i\) 是在 \(j\) 中还是 \(i-j\) 中。有:

\[d_{i,j}=p^{i-j}d_{i-1,j-1}+(1-p)^jd_{i-1,j} \]

时间复杂度 \(O(n^2)\)

CF804F Fake bullions

给定一张 \(n\) 个点的竞赛图,第 \(i\) 个点上有 \(S_i\) 个人,编号从 \(0\)\(S_i-1\),其中的某一些人手上有真金条。

在时刻 \(T\),如果从 \(u\)\(v\) 有一条边,并且 \(u\) 中第 \(T\bmod S_u\) 个人手上有金条(无论真假),并且 \(v\) 中第 \(T \bmod S_v\) 个人没有金条,那么 \(v\) 中第 \(T \bmod S_v\) 个人会获得一个假金条。

无限长时间后他们开始卖出金条。真金条一定会卖出去,而假金条可能卖出去也可能卖不出去。

现在从卖出金条最多的 \(A\) 个点中随机选择 \(B\) 个,问可能选出的不同点集有多少个,对 \(10^9+7\) 取模。

\(1\leq b\leq a\leq n\leq 5\times 10^{3},1\leq s_{i}\leq 2\times10^{6}\)

考虑求出一个点的金条总数 \(mx_i\)(无论真假)。对于两个点 \(x,y\),如果 \(x\) 能到 \(y\),那么若 \(x\)\(i\) 有金条,则最后 \(y\)\(j\) 有金条当且仅当 \(i\equiv j\pmod {\gcd(S_x,S_y)}\)。对于一个强连通分量就是取所有点的 \(\gcd\) 进行计算。竞赛图缩点过后是一条链,所以直接转移。

后面的计数是简单的。

还有一些题可以看 UOB 博客

二分图与霍尔定理

先来几个纯二分图的题目。

P1963 [NOI2009] 变换序列

给出一个长为 \(n\) 的序列 \(a\),你需要给出一个字典序最小的排列 \(p\) 使得 \(a_i=\min(|p_i-i|,n-|p_i-i|)\) 或报告无解。

\(1\leq n\leq 10^4\)

显然对于一个 \(i\),符合条件的 \(p_i\) 最多有 \(2\) 个。我们现在就是要求出二分图字典序最小的完美匹配。我们考虑先跑出一组完美匹配,然后枚举 \(i\)\(p_i\) 最小有多少。考虑一组边 \((u,v)\) 在最大匹配里的充要条件是残量网络上有一个环经过 \((u,v)\)。直接从 \(i\) 出发 dfs,只要不影响前面的匹配即可。时间复杂度 \(O(n(n+m))\)

P4100 [HEOI2013] 钙铁锌硒维生素

给出 \(2\) 组向量 \(a_i,b_i\),每组有 \(n\) 个长为 \(n\) 的向量。求一个字典序最小的排列 \(p\) 使得任意一个 \(a_i\) 被替换成 \(b_{p_i}\) 时,\(a\) 线性无关,或报告无解(\(a\) 本身线性相关时也输出无解)。

\(1 \leq n \leq 300,0\leq a_{i,j},b_{i,j}\leq 10^4\)

考虑我们使用求逆求出 \(b_i\)\(a\) 线性表出的系数 \(c_i\)。考虑若 \(c_{i,j}=0\) 则相当于用 \(b_i\) 换了 \(a_j\) 之后它可以被其他的 \(a\) 线性表出,所以不能换。然后也是二分图字典序最小的完美匹配即可。

P3731 [HAOI2017] 新型城市化

给出一个 \(n\) 个点的无向图,保证原图可以分成两个团。你需要加一条边使得最大团的大小增加。求出哪些边可以达成目标。

输入中给出的是 \(m\) 条边的补图。

\(1\leq n \le 10^4,0 \le m \le \min(1.5\times 10^5,\dfrac{n(n-1)}{2})\)

考虑一个图的最大团就是补图的最大独立集,而原图可以划分成两个团,也就是说补图是二分图,最大独立集等于点数减最大匹配。现在相当于要在补图删去一条边使得最大匹配减少,也就是求一定在最大匹配中的边。根据上文的结论也就是残量网络上没有经过这条边的环,也就是两个端点不在一个强连通分量中。直接 Tarjan 即可。

P7684 [CEOI2005] Depot Rearrangement

\(m\) 种共 \(nm\) 个物品,每种物品 \(n\) 个。现在第 \(nm+1\) 个位置是空地。每次操作可以将一个物品移到空地里面,然后这个位置就变成了空地。最后要求 \(\forall i\in [1,n]\)\([(i-1)m+1,im]\) 这个区间中每种物品出现恰好一次。求最小操作次数,输出方案。

\(1 \leq n,m \leq 400\)

考虑建出二分图。左部第 \(i\) 个点代表第 \(i\) 个长为 \(m\) 的区间,右部点代表颜色。如果一种颜色在区间 \(i\) 里出现了 \(>1\) 次,那么就向这种颜色连次数 \(-1\) 条边。如果没有出现,则颜色向这个点连一条边。考虑图上的一个回路,假设是左部点 \(a\to\) 右部点 $b\to $ 左部点 \(c,\cdots\),则可以是 \(a\) 中的某个颜色 \(b\) 放到 \(c\) 中的一个空位上去。考虑求出原图的欧拉回路然后倒序遍历即可。

P10610 异界之门

给定一棵 \(n\) 个点的带点权的有根树,根为 \(1\),且点 \(i\) 的点权为 \(w_i\)满足对于任意两个深度相同的结点,它们的儿子数也相同

我们进行了一种操作来改变这棵树的点权:选择一条连接了 \((u,v)\) 的边,设 \(u\)\(v\) 的儿子,将 \(w_u\) 加上 \(w_v\)。操作可以被执行任意多次,但是不能重复选择同一条边

给出树的形态以及操作后按照某种 dfs 序写下的点权序列 \(c\),请你恢复操作序列和 dfs 序列。

\(1\le n\le 2000,-10^8\le w_i\le 10^8,-10^{14}\le c_i\le 10^{14}\)

考虑设计 DP。设 \(f_{u,i}\) 表示 \(u\) 子树能否匹配 dfs 序列上的 \([i,i+siz_u-1]\) 这一段。考虑题目中的性质实际上保证了每个点的每个子树大小相同。因此我们可以将 \([i+1,i+siz_u-1]\) 划分成儿子个数个确定区间。考虑一个儿子的权值 \(c_v\) 只有三种可能:\(w_v,w_u+w_v,c_{dfn_u}+w_v\)。如果 \(f_v\) 可以匹配某一段区间,并且点值也是可行的,我们相当于可以这样匹配。我们做二分图最大匹配即可。构造方案是平凡的。

P10683 [COTS 2024] 划分 Particija

集合 $ {1, 2, \ldots, n} $ 的划分为由非空集合组成的集族,满足:

  • \(\forall 1\le i\le n\)\(i\) 出现在恰好一个集合中。

可以用数列 $ [x_1, x_2, \ldots, x_n ]$ 来表示划分。当且仅当 $ x_i = x_j $ 时,$ i $ 和 $ j $ 在同一个集合中。

现有两个划分:第一个划分用数列 $ [a_1, a_2, \ldots, a_n] $ 表示,第二个划分用数列 $ [b_1, b_2, \ldots, b_n] $ 表示。

请求出以下问题的答案:使用这两个划分中的集合,来构造集合 $ {1, 2, \ldots, n} $ 的划分,至少需要多少个集合?

给定参数 \(k\in \{0,1,2\}\)

  • \(k=0\) 时,你需要回答原问题的答案。

  • \(k=1\) 时,允许更改 \(2n\) 个数字(\(a_1,\cdots,a_n,b_1,\cdots,b_n\))中至多一个,最小化构造划分需要的最少集合数。

  • \(k=2\) 时,允许更改 \(2n\) 个数字(\(a_1,\cdots,a_n,b_1,\cdots,b_n\))中至多一个,最大化构造划分需要的最少集合数。

请注意,你需要保证在你修改后,\(\forall 1\le i\le n\)\(1\le a_i,b_i\le n\)

\(1\leq n\leq 2\times 10^5\)

先来做 \(k=0\)。我们构造二分图每个点代表一个集合,把 \(a_i\)\(b_i+n\) 连边,一条边代表两个点选恰好一个。考虑图中的连通块。选了一个点之后,与它同侧的点都是要选的,异侧的点都不选。因此我们取所有连通块左右部点个数的 \(\min\) 加起来即可。对于 \(k\ne 0\),相当于改一条边的一个端点。对于 \(k=1\),因为 \(\min(a,b)+\min(c,d)<\min(a+b,c+d)\),所以我们想拆开一个连通块。枚举割边,考虑当 \(n>1\) 的时候我们一定能把这条边换走且其他连通块答案不变:显然当存在一个新连通块两边都有点的时候直接连到内部即可,否则原来这个连通块肯定是两个点。这时一定存在其他连通块。我们把一个端点改到任意其他连通块更小的那边即可,这样不会改变 \(\min\)。对于 \(k=2\),我们要连接两个连通块。还是枚举修改的边,设这个连通块左部点更少,我们加入(右部点减去左部点)最大的连通块即可(使得两边尽量平衡)。

P10598 BZOJ2162 男生女生

\(n\) 个 Hanghang 和 \(n\) 个 Meatherm。有 \(m\) 对 Hanghang 与 Meatherm 之间有暧昧关系。现在我们想找出这样一个群体,每个 Hanghang 都和每个 Meatherm 之间有暧昧关系,并且总人数最大。注意,Hanghang 数目或者 Meatherm 数目可以为 \(0\)

如果有多个这样的群体,我们选择 Hanghang 最多的那个群体,因为我们觉得 Hanghang 会很不安分。如果这样的群体依然不唯一,他会选择任意一个。

接下来,我们从选出的这个群体的所有暧昧关系中,选出 \(k\) 个进行调查,使得这个群体的所有 Hanghang 和Meatherm,都至少和其中的一对暧昧关系有关系(即是这个暧昧关系的主人公)。请你求出选择的 Hanghang 和 Meatherm 的个数和选关系的总方案数模 \(19921228\) 的值(方案数与选的是哪个群体无关)。

\(1\leq n \leq 50,1\leq m,k \leq 2500\)

第一问相当于求补图的最大独立集,而且要求左部点数量最大化。我们考虑带个权,令左部点的权比右部点大。但是也不能大太多,要先满足人数最大。因此设左部点为 \(n+1\),右部点为 \(n\),跑最小割即可。后面计数容斥一手左右空点数量即可。

P1971 [NOI2011] 兔兔与蛋蛋游戏

游戏在 \(n\)\(m\) 列的棋盘上进行。游戏开始之前,棋盘上有一个格子是空的,其它的格子中都放置了一枚棋子,棋子或者是黑色,或者是白色。

每一局游戏总是 A 先操作,之后双方轮流操作,具体操作为:

  • A 每次操作时,选择一枚与空格相邻的白色棋子,将它移进空格。
  • B 每次操作时,选择一枚与空格相邻的黑色棋子,将它移进空格。

第一个不能按照规则操作的人输掉游戏。现有一局操作次数为 \(k\) 的 A 输给 B 的游戏实录,请你指出这一局游戏中所有 A“犯错误”的地方。A 的操作是“犯错误”的,当且仅当,在这次操作前 A 有必胜策略,而这次操作后 B 有必胜策略。

\(1\leq n,m\leq 40,1\leq k\leq 1000\)

首先转化为移动空格。注意到空格从一个位置移走之后,之后就不会再回来,因为颜色对不上。考虑这个很像二分图,一个人每次移动到黑点或白点上。建立二分图相当于在上面博弈。根据经典结论先手必胜当且仅当起点不在任何一个最大匹配上。相当于每次删掉一个点询问最大匹配。我们时光倒流,依次加点推流即可。

霍尔定理

性质

性质 1(霍尔定理):对于一个二分图的左部点的子集 \(S\),定义 \(N(S)\) 为右部点中与 \(S\) 有连边的点的集合。记二分图左部点集合为 \(V_1\),右部点集合为 \(V_2(|V_1|\leq |V_2|)\),霍尔定理声称:这张图存在完美匹配,当且仅当 \(\forall S\subseteq V_1,|N(S)|\ge |S|\)

性质 1 证明:先证必要性:对于 \(S\),若 \(|N(S)|<|S|\),则 \(S\) 一定不能匹配完,必要性得证。对于充分性,我们考虑归纳证明。对于 \(n=1\) 显然成立。若存在 \(S\subsetneq V_1,|S|=|N(S)|\),显然根据假设 \(S\) 有完美匹配。删去 \(S,N(S)\) 后若存在 \(T\subseteq V_1\setminus S,|T|<|N(T)|\),则有 \(|S\cup T|<|N(S\cup T)|\),不满足题设。因此此时得证。否则我们有 \(\forall S\subsetneq V_1,|N(S)|>|S|\)。我们任选一条边并把它的端点删去,此时仍有 \(\forall S\subseteq V_1',|N(S)|\ge |S|\)。因此霍尔定理得证。

性质 1 推论 1:二分图存在一个大小为 \(|V_1|-a\) 的匹配,当且仅当 \(\forall S\subseteq V_1,|N(S)|+a\ge |S|\)

证明与性质 1 证明类似。

性质 1 推论 2:易证二分图的最大匹配为 \(|V_1|-\max\limits_{S\subseteq V_1}(\max(0,|S|-|N(S)|))\)

性质 1 推论 3:设二分图建出网络流模型后左部点 \(i\in V_1\) 的流量为 \(c_i\),则左部点全部流满当且仅当 \(\forall S\subseteq V_1,|N(S)|\ge \sum\limits_{i\in S}c_i\)

拆点同样证即可。

例题

P3488 [POI2009] LYZ-Ice Skates

滑冰俱乐部初始有 \([1,n]\) 号码溜冰鞋各 \(k\) 双,已知 \(x\) 号脚的人可以穿 \([x,x+d]\) 号码的鞋子。

现在有 \(m\) 次操作,每次两个数 \(r,x\),表示来了 \(x\)\(r\) 号脚的人,\(x\) 为负则表示离开。在每次操作之后,你需要判断溜冰鞋是否足够。

\(n\le 2\times 10^5,m\le 5\times 10^5,k\le 10^9,1\le r_i\le n-d,-10^9\le x_i\le 10^9,0\le d<n\)

考虑霍尔定理。我们发现限制最紧的左部点集合一定是一段区间,并且连到右部点之后全部是连续的。设 \(a_i\) 表示 \(i\) 号脚的人数,我们有: \(\forall l,r\in [1,n]\land l\leq r,\sum\limits_{i=l}^{r}a_i\leq k(r+d-l+1)\)。相当于 \(\sum\limits_{i=l}^{r}(a_i-k)\leq kd\)。维护最大子段和即可。

P11225 [COTS 2019] 疏散 Sklonište

给定 \(n\) 个点 \(m\) 条边的无向连通图,边有边权。有 \(k\) 个关键点 \(A_1,A_2,\cdots,A_k\)容量\(S_1,S_2,\cdots,S_k\)

你需要构造一个序列 \(B_1,B_2,\cdots,B_n\),使得:

  • \(\forall 1\le i\le n\)\(1\le B_i\le k\)

  • 对于 \(1\le i\le k\),定义 \(\displaystyle \mathrm{cnt}_i=\sum_{1\le j\le n} [B_j=i]\),也就是 \(i\)\(B\) 序列中出现的次数。则 \(\mathrm{cnt}_i\le S_i\)

定义序列 \(B\)疏散时间\(\displaystyle \max_{1\le i\le n} \operatorname{dist}(i,A_{B_i})\),其中 \(\operatorname{dist}(u,v)\) 指图中 \(u,v\) 间最短路的长度。

求出疏散时间的最小值。保证 \(\sum S_i\ge n\)

\(1\le n\le 10^5,n-1\le m\le 3\times 10^5,1\le k\le 17,1\le w,S_i\le 10^9\)

先预处理出每个点到关键点的最短路。然后二分答案,相当于保留了一些边要看左部点有没有匹配完。考虑枚举左部点显然不可行。我们枚举右部点,看左部点哪些与它们有连边。使用高维前缀和即可。

TopCoder 11513 OrthogonalAnagram

给出一个长为 \(n\) 的字符串 \(a\)。你需要重排这个字符串变成 \(b\),满足字典序最小,而且 \(\forall i\in[1,n],a_i\ne b_i\)。输出方案或判定无解。

\(1\leq n\leq 5\times 10^4,\sum\) 为小写英文字母。

考虑直接贪心枚举字符,现在就是要求后面是否满足条件。考虑二分图上一个字符向与它不相同的字符连边,使用霍尔定理。注意到左边选两个不同的字符,右边就是全集,一定符合条件,所以左边一定全选相同的字符。枚举这个字符判定即可。

P4518 [JSOI2018] 绝地反击

每个飞船都可以看做是平面上的一个点,第 \(i\) 艘飞船的坐标为 \((x_i,y_i)\) 。外星母舰位于坐标原点 \((0,0)\)

为了实现最高效的打击,所有飞船都必须移动到攻击轨道上。攻击轨道是圆心在原点 \((0,0)\) 、半径为 \(R\) 的圆。我们希望所有 \(n\) 艘飞船均匀地排列在攻击轨道上(顺序随意),即相邻飞船在攻击轨道(圆弧)上的距离相等且恰好等于 \(\frac{2\pi R}{n}\)

请计算出打击开始的最短时间(即所有飞船移动到攻击轨道上并等距排列的最少时间)。飞船一单位时间可以在平面上移动一单位距离,且飞船的体积可以看成 \(0\) 。因此在你设计的方案中,飞船在某个时刻“相遇”是允许的。此外,初始时飞船的坐标也允许重合。

\(3 \le n\le 200,0 \le| x_i|,| y_i|,R\le 100\)

考虑二分答案。相当于每个飞船有一个能到的圆。注意到肯定有一个飞船刚好移动到圆周与攻击轨道的交点处,否则答案可以更小。我们固定这个飞船的最终位置,那么所有的最终点都确定了。现在可以一个飞船向能到的最终点(一个区间)连边,求是否有完美匹配。考虑霍尔定理。因为左部点连右部点的区间没有很好的性质,因此我们枚举右部点区间,看左部点有哪些被完全包含了。使用扫描线 + 线段树优化可以做到 \(O(n^2\log n\log V)\)

P9339 [JOISC 2023 Day3] Cookies

\(n\) 种物品装盒。第 \(i\) 种物品有 \(A_i\) 个。应满足以下条件:

  • 一个盒子中的物品种类不同。

  • 一个盒子中的物品数量等于以下 \(m\) 个数字之一:\(B_1,B_2,⋯ ,B_m\)

求出盒子数最小的方案,或报告无解。

\(1\leq n\leq 15000,A_i\ge 1,\sum A_i\leq 15000,1\leq m,B_i\leq n,B_i < B_{i+1}\)

假设我们确定了盒子的大小序列为 \(C\),考虑构建二分图。左部点是盒子,右部点是物品。每个左部点向每个右部点连 \(1\) 边,右部点连 \(A_i\) 边。应用霍尔定理:对于一个左部点集合 \(S\),合法的条件是 \(\sum\limits_{i\in S}C_i\leq\sum\limits_{i=1}^{n}\min(A_i,|S|)\)。右边只与集合大小有关。左边肯定选最大的 \(|S|\) 个。这样我们可以求出 \(lim_i\) 表示选了 \(i\) 个盒子,\(\sum C_i\) 的上限。现在就是求非递增序列 \(C\) 使得和为 \(\sum A_i\),前缀和不超过 \(lim_i\),元素在 \(B\) 内。考虑 DP。设 \(f_{i,j}\) 表示最大的 \(i\) 个元素和为 \(j\) 是否可行,每次加一个元素做完全背包。考虑如果加到了一个 \(x\),因为所有元素都 \(\ge x\),所以 \(i\) 的上界是 \(\dfrac{n}{x}\),再使用 bitset 优化就是 \(O(\dfrac{n^2\log n}{w})\) 的。

Prufer 序列

定义及性质

一棵 \(n\) 个点有标号无根树的 Prufer 序列是一个长为 \(n-2\) 的正整数序列。它是这样构建的:

  • 取出树上编号最小的叶子,将它连接到的点的编号加入序列末尾,然后将它删除。
  • 重复上述步骤直到只剩 \(2\) 个点。

对于 Prufer 序列的构建,我们有一个 \(O(n)\) 做法:记一个变量 \(x\) 表示编号最小的叶子,删去后检查连到的点是否变成了叶子。如果是,并且它的的编号比 \(x\) 小,则立即删去并继续检查,否则不动。从小到大枚举 \(x\) 即可。

我们可以看出一个关键性质:每个结点在 Prufer 序列中出现的次数是其度数减 \(1\)(没有出现的就是叶结点)。

重建树的方法是类似的。根据 Prufer 序列的性质,我们可以得到原树上每个点的度数。然后你也可以得到编号最小的叶结点,而这个结点一定与 Prufer 序列的第一个数连接。然后我们同时删掉这两个结点的度数。

同线性构造 Prufer 序列的方法。在删度数的时侯会产生新的叶结点,于是判断这个叶结点与现在这个点的大小关系,如果更小就优先考虑它。时间复杂度 \(O(n)\)

对于树计数问题,我们可以考虑转成 Prufer 序列的计数问题。

例题

板子:P6086 【模板】Prufer 序列

UVA10843 Anne's game

\(n\) 个点的有标号无根树的个数,答案对 \(2\times 10^9+11\) 取模。

\(1\leq n\leq 100\)

转成 Prufer 序列计数。答案就是 \(n^{n-2}\)。这就是 Caylay 公式。

P5454 [THUPC2018] 城市地铁规划

我们要在 \(n\) 个点之间建边。任意两个点之间都可以建。如果有 \(d\) 条边经过了某个点,那么该点的便利度为 \(f(d)\bmod 59393\),其中 \(f(x)=\sum\limits_{i=0}^{k}a_ix^i\)。我们要建出一棵树,请问使得所有点便利度之和最大的方案是什么。

\(1\leq n\leq 3000,1\leq k\leq 10,0\leq a_i\leq 50\)

考虑我们知道了每个点的度数就可以使用 Prufer 序列转化为树。直接 DP 度数即可。

CF156D Clues

给定一个 \(n\) 个点 \(m\) 条边的带标号无向图,记它有 \(s\) 个连通块,求添加 \(s-1\) 条边使得整个图连通的方案数,答案对 \(p\) 取模。

\(1\leq n\leq 10^5,0\leq m\leq 10^5,1\leq p\leq 10^9\)

设每个连通块的点数为 \(w_i\),我们仿照 Prufer 序列进行构建:对所有连通块钦定一个顺序,每次删掉最小的,记录下它连出去的边的另一个端点的编号(不是连通块编号)。这样的序列有 \(n^{s-2}\) 个。对于每个序列的每个元素,我们发现这个连出去的边在删去的连通块内的点是不定的。除了最后两个连通块,其他都有 \(w_i\) 的贡献。最后两个 \(x,y\) 之间的那条边也有 \(w_xw_y\) 的贡献,总贡献就是 \(\prod\limits_{i=1}^s w_i\)。答案就是 \(n^{s-2}\prod\limits_{i=1}^s w_i\)

P2290 [HNOI2004] 树的计数

一个有 \(n\) 个节点的树,已知第 \(i\) 个节点 \(v_i\) 的度数为 \(d_i\),问满足这样的条件的不同的树有多少棵。

\(1\le n\le 150,0\leq d_i\leq n-1\),答案不超过 \(10^{17}\)

对 Prufer 序列计数,答案就是 \(\dfrac{(n-2)!}{\prod\limits_{i=1}^n (d_i-1)!}\)

P2624 [HNOI2008] 明明的烦恼

和上一题一样。不同的是某些点的度数没有被规定。

\(1\le n\le 1000\)

先对规定了的 \(cnt\) 个点 \(s_1,s_2,\cdots,s_{cnt}\) 求出在 Prufer 序列中的排列方案数。相当于剩下的每个位置都能填 \(n-cnt\) 个数。设 \(sum=\sum\limits_{i=1}^{cnt}(d_{s_i}-1)\),答案是 \({n-2\choose sum}\dfrac{sum!}{\prod\limits_{i=1}^{cnt}(d_{s_i}-1)!}(n-cnt)^{n-2-sum}\)

HDU 5629 Clarke and tree

\(n\) 个点,点 \(i\) 的度数不超过 \(a_i\)。求在这些点里面选 \(s\) 个点构成一棵树的方案数。对每个 \(s\) 都输出。答案对 \(10^9+7\) 取模。

\(2\leq n\leq 50,1\leq a_i<n\)

考虑 DP。设 \(f_{i,j,k}\) 表示前 \(i\) 个点选了 \(j\) 个点,Prufer 序列长为 \(k\) 的方案数。我们有:

\[f_{i,j,k}=f_{i-1,j,k}+\sum_{l=0}^{a_i-1}f_{i-1,j-1,k-l}{k\choose l} \]

直接计算即可。

AT_abc303_h [ABC303Ex] Constrained Tree Degree

和 P2290 一样。不同的是每个 \(d_i\) 都可以是集合 \(S\) 中任意元素。

\(2\leq n\leq 2\times 10^5,1\leq |S|,S_i\leq n-1\)

考虑还是写出式子:\((n-2)!\prod\limits_{i=1}^n \dfrac{1}{(d_i-1)!}\)。考虑后面相当于是选 \(n\)\(S\) 中的元素使得和等于 \(2n-2\)。每个元素减去一,和就是 \(n-2\)。这个显然可以多项式快速幂。双倍经验:P5219 无聊的水题 I

P11039 【MX-X3-T6】「RiOI-4」TECHNOPOLIS 2085

约定 \(\operatorname{lca}_G(u,v)\) 表示编号为 \(u,v\) 的结点在有标号有根树 \(G\) 上的 LCA。给定一棵根编号为 \(1\),结点编号为 \(1\sim n\) 的有根树 \(T\) 与一个点集 \(S\)。你需要求出有多少个结点编号为 \(1\sim n\) 的有根树 \(T'\),满足对于任意 \(u,v\in S\),有 \(\operatorname{lca}_T(u,v)=\operatorname{lca}_{T'}(u,v)\)。答案对 \(998244353\) 取模。

\(2\le |S|\le n\le 10^6\)

显然要求虚树相等。设虚树大小为 \(m\),我们钦定一下新树的根。先假定它就是虚树的根。其他的点要么插到边上,要么接在点上。枚举前者的个数 \(i\)。前者的贡献就是 \((m-1)^{\overline{i}}\),后者相当于一个 \(m+i\) 的块和 \(n-m-i\) 个散点合并。使用 Prufer 序列,贡献是 \(n^{n-m-i-1}(m+i)\)。总的答案就是 \(ans_{n,m}=\sum\limits_{i=0}^{n-m}{n-m\choose i}(m-1)^{\overline{i}}n^{n-m-i-1}(m+i)\)。对于新树的根不是虚树根的情况,根有 \(n-m\) 种情况。我们把这个根也加入虚树,然后重新计算即可。答案就是 \(ans_{n,m}+(n-m)ans_{n,m+1}\)

Codechef COMBIISFUN Combinatorics Is Fun

对于长度均为 \(n\) 的整数数列对 \((A,B)\) 计数,满足:\(\forall i\in [1,n]A_i\ne B_i,1\leq A_i,B_i\leq n\),且存在数列 \(C\) 使得 \(C_i\in \{A_i,B_i\}\)\(C\) 是排列。对质数取模。

\(1\leq n\leq 2000\)

考虑转化条件。我们在一个 \(n\) 个点的图上对所有 \((A_i,B_i)\) 连边,易得这个图成立当且仅当每个连通块都是一棵基环树。因为 \(A_i\ne B_i\) 所以没有自环。设答案为 \(f_n\),先枚举第一个连通块的大小,钦定 \(1\) 被选了,我们有:

\[f_n=\sum_{i=2}^n f_{n-i}{n-1\choose i-1}{n\choose i}g_i \]

其中 \({n\choose i}\) 是枚举连通块中 \(i\) 条边在数列上的位置。

对于 \(g_n\),我们枚举环长 \(i\),环上的边有 \(\dfrac{(i-1)!}{2}\) 种方案。其他的点使用 Prufer 即可。有:

\[g_n=\sum_{i=2}^{n}{n\choose i}\dfrac{(i-1)!}{2}in^{n-i-1}n!2^n \]

其中 \(n!\) 是这 \(n\) 条边进行排列,\(2^n\)\(A,B\) 的排列。

P4002 [清华集训2017] 生成树计数

在一个 \(s\) 个点的图中,存在 \(s-n\) 条边,使图中形成了 \(n\) 个连通块,第 \(i\) 个连通块中有 \(a_i\) 个点。

现在我们需要再连接 \(n-1\) 条边,使该图变成一棵树。对一种连边方案,设原图中第 \(i\) 个连通块连出了 \(d_i\) 条边,那么这棵树 \(T\) 的价值为:

\[\left(\prod_{i=1}^{n} {d_i}^m\right)\left(\sum_{i=1}^{n} {d_i}^m\right) \]

求出所有生成树的价值之和,对 \(998244353\) 取模。

\(1\leq n \le 3\times 10^4,0\leq m \le 30\)

对于一个固定的 \(d\),先将每个数减去 \(1\),然后直接使用 Prufer 序列写出答案:

\[\begin{aligned} ans&=\dfrac{(n-2)!}{\prod\limits_{i=1}^{n} d_i!}\left(\prod_{i=1}^{n} {(d_i+1)}^ma_i^{d_i+1}\right)\left(\sum_{i=1}^{n} {(d_i+1)}^m\right)\\ &=(n-2)!\prod_{i=1}^{n}a_i\sum_{j=1}^n\left(\left(\prod\limits_{i=1}^{n}\dfrac{a_i^{d_i}}{d_i!}\right)(d_j+1)^{2m}\prod_{i=1,i\ne j}^{n} {(d_i+1)}^m\right) \end{aligned} \]

前面是定值,后面的 \(\sum\),设 \(F(x)\) 是这个关于 \(\sum\limits_{i=1}^nd_i\) 的生成函数。我们设:

\[\begin{aligned} A(x)&=\sum_k \dfrac{1}{k!}(k+1)^mx^k\\ B(x)&=\sum_k \dfrac{1}{k!}(k+1)^{2m}x^k \end{aligned} \]

则:

\[\begin{aligned} F(x)&=\sum_{i=1}^n\left(B(a_ix)\prod_{j=1,j\ne i}^nA(a_jx)\right)\\ &=\left(\sum_{i=1}^n\dfrac{B(a_ix)}{A(a_ix)}\right)\left(\prod_{i=1}^nA(a_ix)\right)\\ &=\left(\sum_{i=1}^n\dfrac{B(a_ix)}{A(a_ix)}\right)\exp\left(\sum_{i=1}^n\ln A(a_ix)\right)\\ \end{aligned} \]

考虑 \(\sum\limits_{i=1}^n\dfrac{B(a_ix)}{A(a_ix)}\)\(\sum\limits_{i=1}^n\ln A(a_ix)\) 只需算出 \(\dfrac{B(x)}{A(x)}\)\(\ln A(x)\) 之后第 \(k\) 项乘上 \(\sum\limits_{i=1}^na_i^k\) 即可。考虑这个东西怎么求,还是写出 \(\sum\limits_k a_i^k\) 的生成函数 \(\dfrac{1}{1-a_ix}\)。有:

\[\begin{aligned} \sum_{i=1}^n\dfrac{1}{1-a_ix}&=\sum_{i=1}^n\left(1+\dfrac{a_ix}{1-a_ix}\right)\\ &=n-x\sum_{i=1}^n\dfrac{-a_i}{1-a_ix}\\ &=n-x\sum_{i=1}^n\ln'(1-a_ix)\\ &=n-x\ln'\left(\prod_{i=1}^n(1-a_ix)\right)\\ &=n-x\dfrac{\left(\prod\limits_{i=1}^n(1-a_ix)\right)'}{\prod\limits_{i=1}^n(1-a_ix)} \end{aligned} \]

分治 FFT 即可。

树分治形态问题

点分树和边分树是树分治中的常用结构。这里是形态问题而不是数据结构问题。

例题

QOJ #5357. 芒果冰加了空气

大家都会了。

P5912 [POI2004] JAS

给出一棵 \(n\) 个点的树,求它的点分树的最小深度。

\(1\leq n\leq 5\times 10^4\)

考虑和上面一题一样,还是从子树向上合并。考虑对每个点赋一个权值 \(d_i\) 表示它是倒数第 \(d_i+1\) 次选的,对于两个点 \(x,y(d_x=d_y)\),它们的路径上必然至少有一个点 \(z\) 满足 \(d_z>d_x\),否则就不满足性质。考虑维护一个子树里现在还没有满足限制的 \(d\) 的集合(也就是到子树根路径上没有权值 \(>d_i\) 的点)。每次显然这个点的 \(d\) 越小越好。首先,如果一个值在超过一个子树中出现了,这个点的 \(d\) 要大于它。而且这个 \(d\) 不能存在于子树集合中。考虑点分树经典结论,答案不超过 \(O(\log n)\),使用二进制压位即可。双倍经验:AT_agc009_d [AGC009D] Uninity

CF1444E Finding the Vertex

给出一棵 \(n\) 个点的树,求它的边分树的最小深度。需要求出方案。

\(1\leq n\leq 100\)

同样的对每条边赋一个权值,向上合并。对于一个子树还是求出它里面的集合,现在就是分配一个点连向所有儿子的边的权值。一样的,权值需要与子树中的不同。考虑分配了一个 \(d\) 之后,所有小于 \(d\) 的限制都没用了。还有,所有连边的权值集合不能有交。现在对于一个 \(u\) 相当于有 \(deg_u-1\) 个数 \(a_i\),对于每个 \(i\) 求一个 \(b_i>a_i\) 满足 \(\bigwedge\limits_{i=1}^{deg_u-1} b_i=0,a_u=\sum\limits_{i=1}^{deg_u-1} b_i\) 最小。考虑先把 \(a_u\) 赋成 \(\infty\),每次把最高位换成 \(0\) 然后看是否合法。我们从高到低考虑现在的 \(a_u\),如果这一位是 \(1\),考虑所有的 \(a_i\),如果有更高位是 \(1\) 的,不合法。如果有这一位是 \(1\) 的,显然可以把这个 \(a_i\) 的这一位赋成 \(0\)。否则可以消除一个 \(a_i\) 的影响。我们每次显然都是考虑最大的 \(a_i\),使用优先队列即可(可以同时求出方案)。因为答案的上界是 \(n\),所以可以使用 bitset__int128。总复杂度 \(O(n^3\log n)\)

其实对于那个子问题可以做到 \(O(n\log n)\),详情请见 P9293 [ROI 2018] Addition without carry 题解区。

posted @ 2024-12-26 08:07  zhicheng123  阅读(169)  评论(4)    收藏  举报