# 二分图:染色、不变量与构造选择 > 先完成 [课前零食:两支队伍与奇怪的圈](00-课前零食-两支队伍与奇怪的圈.md),再把“奇环冲突”带进构造题。 ## 本节目标 学完后,你应能用奇环刻画二分图,处理非连通分量的两种翻转选择,并把“每点只能做源或汇”“三标签相邻差 1”等构造条件还原成二分染色。 ## 前置知识与课前自测 前置:BFS/DFS、连通分量、0/1 背包。 1. 一个图可二染当且仅当没有什么结构? 2. 每个连通二分分量的染色是否唯一? 3. 给无向边定向后,怎样保证不存在长度 2 的有向路径?
自测答案 1. 奇环。 2. 在整体翻转两侧颜色的意义下唯一;非连通图每个分量可独立翻转。 3. 让每个点要么所有边都出、要么所有边都入;相邻点必须属于相反类型。
## 问题动机与核心知识 从任一点染 0,沿边交替染色。遇到同色边时,DFS/BFS 树上两条到根路径与该边形成奇环;反之奇环无法交替回到起点原色。因此“可二染”和“无奇环”充要。 一个连通分量的两侧集合记为 $A_i,B_i$。所有合法二染只能选“$A_i$ 为颜色 0”或整体交换。若题目还规定某颜色恰有 $K$ 个点,就转成从每个分量选择 $|A_i|$ 或 $|B_i|$ 的分组背包,并保存决策恢复方案。 ## 实现指南 - 颜色初始化为 -1,非连通图从每个未染点启动。 - 孤立点也是一个分量,两侧大小可视为 1 与 0。 - 恢复背包时记录“到达和 $s$ 的分量选择”,不能只有可达布尔值。 - 构造输出必须回到原输入顺序;保存边端点或对象编号。 ## 精选例题 1:Graph Without Long Directed Paths ### 来源信息与题意 - VJudge:[CodeForces-1144F Graph Without Long Directed Paths](https://vjudge.net/problem/CodeForces-1144F) - 原题:[Codeforces Round 550 (Div. 3)](https://codeforces.com/problemset/problem/1144/F) - 难度:1700;考点:二分图充要性、边定向输出 连通简单无向图有 $n,m\le2\times10^5$。给所有边定向,使有向图中不存在长度至少 2 的路径;若可行,按输入边输出 0/1 方向串。
Hint 1若某点同时有入边和出边,就立刻出现长度 2 路径。
Hint 2因此每个点必须是“纯源”或“纯汇”,相邻点类型相反。
Hint 3二分染色后统一从颜色 0 指向颜色 1。
### Observations、Editorial 与证明 不存在长度 2 路径等价于没有点同时作为某条边终点和另一条边起点,所以每点必须纯入或纯出,邻点类型相反,原图必须二分。若二分,所有边从一侧指向另一侧,任一有向路径走一步就到纯汇,无法继续,构造成立。 时间 $O(n+m)$,输出位由输入方向与颜色比较决定。 ### 核心伪代码与参考实现附件 ```text two-color the graph if an edge has equal-colored endpoints: output NO otherwise orient every edge from color 0 to color 1 translate each orientation back to a 0/1 character in input order ``` 完整 GNU C++17 参考实现见附件:[CodeForces-1144F.cpp](../../参考实现/07-二分图/CodeForces-1144F.cpp) ### 复盘与变式 若只要求无有向环,可以按任意顶点序给边从小到大定向,并不要求二分;“禁止长度 2”远强于“禁止环”。 ## 精选例题 2:Graph Coloring ### 来源信息与题意 - VJudge:[CodeForces-1354E Graph Coloring](https://vjudge.net/problem/CodeForces-1354E) - 原题:[Educational Codeforces Round 87](https://codeforces.com/problemset/problem/1354/E) - 难度:2100;考点:分量二染、分组背包、构造恢复 简单无向图有 $n\le5000,m\le10^5$,需恰用 $n_1,n_2,n_3$ 个标签 1、2、3,并使每条边两端标签差恰为 1。输出任一方案或 `NO`。
Hint 1边只可能连接 1–2 或 2–3,所以标签 2 与非 2 构成二分两侧。
Hint 2每个连通分量必须选择其中一侧全标 2;目标是总数恰为 $n_2$。
Hint 3对各分量两侧大小做 0/1 分组背包,并保存选择。
Hint 4剩余点之间没有边,可任取 $n_1$ 个标 1,其余标 3。
### Observations、Editorial 与证明 任意边必须一端为 2,另一端为 1/3,所以图必须二分,且每个连通分量的某一整侧为 2。背包选择各分量哪侧,使总大小 $n_2$。选定后,所有非 2 点只与 2 相邻,它们之间无边,故任取 $n_1$ 个标 1 不会破坏条件。 反之任何合法标号诱导上述二分与分量选择,所以算法充要。染色 $O(n+m)$,背包 $O(n^2)$,适合 $n=5000$。 ### 核心伪代码与参考实现附件 ```text two-color every connected component and store its two sides group-knapsack: from each component choose one side so total chosen size is n2 recover choices; label chosen side 2 among all remaining vertices label any n1 as 1 and the rest as 3 ``` 完整 GNU C++17 参考实现见附件:[CodeForces-1354E.cpp](../../参考实现/07-二分图/CodeForces-1354E.cpp) ### 实现细节与复盘 `choice[i][sum]` 保存到达状态时第 $i$ 个分量选哪侧;同一状态被覆盖无妨,只需恢复任一路径。`need3` 由总数自动满足,但读入保留以对应题意。 ## 精选例题 3:Arpa’s overnight party ### 来源信息与题意 - VJudge:[CodeForces-741C Arpa’s overnight party and Mehrdad’s silent entering](https://vjudge.net/problem/CodeForces-741C) - 原题:[Codeforces Round 383 (Div. 1)](https://codeforces.com/problemset/problem/741/C) - 难度:2600;考点:构造辅助边、偶环二染 $n\le10^5$ 对情侣坐在环形排列的 $2n$ 张椅子上,每椅恰一人。给每人两种食物,要求情侣不同,且任意连续三人不能全相同。输出方案。
Hint 1若强制椅子 `(1,2),(3,4),...` 中两人不同,则任意连续三椅必包含这样一对。
Hint 2再给每对情侣连“必须不同”边。每个椅子恰连一条固定相邻边和一条情侣边。
Hint 3所得多重图每点度数为 2,分量是偶环(两类边交替),可二染。
### Observations、Editorial 与证明 建立 $2n$ 个椅子点,加入情侣边与固定配对边 $(1,2),(3,4),\ldots$。每点各属于一条两类边,所以沿环行走两类边交替,所有环长度为偶数,必可二染。二染保证情侣不同,也保证每个固定椅对不同;任意三个连续椅子中包含一个完整固定对,因此不会三人同色。 复杂度 $O(n)$。情侣恰坐固定对时会出现两条平行边,但不影响二染。 ### 核心伪代码与参考实现附件 ```text make one vertex for each chair add an inequality edge for every romantic pair add inequality edges (1,2), (3,4), ... two-color every resulting even-cycle component output the two colors at each romantic pair's chair positions ``` 完整 GNU C++17 参考实现见附件:[CodeForces-741C.cpp](../../参考实现/07-二分图/CodeForces-741C.cpp) ### 复盘与变式 技巧不是“任意把相邻椅子配对”,而是选一组不交叠相邻对,使每个长度 3 窗口至少覆盖一对。若椅子数为奇数,这种完美配对不存在,构造需重新设计。 ## 扩展与联系 ## 高阶例题:Choosing Points ### 来源信息与题意 - VJudge:[AtCoder-agc025_d Choosing Points](https://vjudge.net/problem/AtCoder-agc025_d) - 原题:[AtCoder Grand Contest 025 D](https://atcoder.jp/contests/agc025/tasks/agc025_d) - 难度:AGC 800 分;考点:距离图二染、数论奇偶性、两次染色取交 给定 $N,D_1,D_2$,其中 $1\le N\le300$,$1\le D_1,D_2\le2\times10^5$。从所有满足 $0\le x,y<2N$ 的格点中选出 $N^2$ 个,使任意两点的距离都不等于 $\sqrt{D_1}$ 或 $\sqrt{D_2}$。 这题的难点不是搜索点集,而是证明每一种平方距离都能把整张格点图切成两侧。
Hint 1:先只禁止一个距离 把每个格点看成点,距离平方为 $D$ 的两点连边。若能把这张图二染,同色点集就不会包含禁边。
Hint 2:距离平方的模 4 信息 若 $D$ 为奇数,则 $\Delta x,\Delta y$ 一奇一偶;若 $D\equiv2\pmod4$,则二者都为奇数。分别考虑 $(x+y)\bmod2$ 与 $x\bmod2$。
Hint 3:$4\mid D$ 怎么办 $\Delta x^2+\Delta y^2\equiv0\pmod4$ 强迫 $\Delta x,\Delta y$ 都是偶数。把坐标同时除以 2,问题缩成距离平方 $D/4$;点的颜色可以递归地由 $(\lfloor x/2\rfloor,\lfloor y/2\rfloor)$ 决定。
Hint 4:同时禁止两个距离 分别得到两位颜色 $(c_1,c_2)$,把 $4N^2$ 个格点分进四个桶。鸽巢原理保证某桶至少有 $N^2$ 个点。
### Observations 1. 直接贪心选点需要动态检查大量平方距离;更重要的是,它解释不了题目保证的“任意 $D_1,D_2$ 都有解”。改看禁距图后,目标变成找一个大独立集。 2. 一般图的最大独立集仍然困难;本题真正删掉搜索的是“每个禁距图都可显式二染”。只禁止 $D$ 时,同一颜色类天然是独立集。 3. $D$ 的全部素因子并不重要。不断删除因子 4 后,只剩“奇数”或“模 4 余 2”两种奇偶骨架;它们分别由棋盘色和横坐标奇偶处理。 4. 对两个禁距图不必求公共独立集。两次二染交叉成四类,同一类在两张图中都独立;四类平均大小恰为 $N^2$。 ### Editorial、正确性与复杂度 定义 `color(x,y,D)`:只要 $4\mid D$,就令 $D\leftarrow D/4$ 且 $x\leftarrow\lfloor x/2\rfloor,y\leftarrow\lfloor y/2\rfloor$。终止后: - 若 $D$ 为奇数,返回 $(x+y)\bmod2$; - 若 $D\equiv2\pmod4$,返回 $x\bmod2$。 证明它是距离图的合法二染。设两格点差为 $(u,v)$ 且 $u^2+v^2=D$。当 $4\mid D$ 时,平方模 4 只能是 0 或 1,因此 $u,v$ 必须同为偶数;约去 2 后仍是同一形式。约分终止后,若 $D$ 奇,则 $u,v$ 一奇一偶,$(x+y)$ 奇偶必翻转;若 $D\equiv2\pmod4$,则 $u,v$ 都奇,$x$ 奇偶必翻转。因此每条距离平方为 $D$ 的边两端异色。 对 $D_1,D_2$ 分别算颜色,把点放入编号 `2*c1+c2` 的桶。同桶两点在两种染色下都同色,故不可能相距 $\sqrt{D_1}$ 或 $\sqrt{D_2}$。总点数为 $(2N)^2=4N^2$,至少一个桶有 $N^2$ 个点,取其中任意 $N^2$ 个即可。这同时证明构造不漏解目标,也说明无需尝试不同起点或回溯。 枚举格点的时间为 $O(N^2\log\max(D_1,D_2))$,空间为 $O(N^2)$;递归层数只等于因子 4 的个数。 ### 核心伪代码与参考实现附件 ```text function color(x, y, D): while D % 4 == 0: D = D / 4 x = floor(x / 2) y = floor(y / 2) if D is odd: return (x + y) % 2 return x % 2 make four empty buckets for x in 0 .. 2*N-1: for y in 0 .. 2*N-1: key = 2*color(x,y,D1) + color(x,y,D2) append (x,y) to bucket[key] output any N*N points from a bucket whose size is at least N*N ``` 完整 GNU C++17 参考实现:[AtCoder-agc025_d.cpp](../../参考实现/07-二分图/AtCoder-agc025_d.cpp) ### 实现细节、复盘与变式 - 这里除的是点坐标本身的整数商;对一条实际禁距边,两端在每层的坐标差都是偶数,所以该染色证明不受低位舍弃影响。 - 不要枚举满足 $u^2+v^2=D$ 的位移,颜色公式已经同时处理全部位移。 - 识别信号是“两个关系各自可二染,但需要同时独立”;可迁移方法是取颜色向量,再用鸽巢原理选最大交类。 - 若禁距数增加到 $k$ 个,同样会得到 $2^k$ 个桶,只能保证最大桶至少有总点数的 $2^{-k}$;本题的常数 `2N` 正好与两个约束匹配。 ## 扩展与联系 - 二分图判定也可返回一条奇环作为不可行证据:遇到同色边后沿 BFS 父链找公共祖先。 - 分量翻转 + 背包是常见结构,出现“每块二选一且总量固定”应主动识别。 - 2-SAT 能表达更一般的二选一冲突;本节图染色是其更特殊且更快的情形。 ## 总结与自检 1. 同色边怎样构造奇环证据? 2. 无长度 2 有向路径为何等价于纯源/纯汇二分? 3. 三标签题为什么标签 2 必须占每个分量完整一侧? 4. 派对题新增固定配对边解决了哪个瓶颈? ## 课后训练建议 第一题应独立完成;第二题先只求是否能选出 $n_2$,再加恢复;第三题不看代码手画 3 对情侣的辅助图。复盘时把每题的“二分两侧分别代表什么”写成一句语义,而不是只写颜色 0/1。