捧杯 ~ 图染色

学习了 pb 大师的集训队论文 《图染色问题初探》
很有趣!
论文介绍了如下几个(并没有相互关联的)问题:

  • 离线边染色
  • 平面图 5 染色的构造
  • 离线三分图染色问题,给出了多项式时间内 O ( n 1 / 2 ) O(n^{1/2}) O(n1/2) 种颜色的简单的做法,以及我看不懂的 O ( n 2 / 5 ) O(n^{2/5}) O(n2/5) 种颜色的做法 /kk。
  • 在线特殊图染色:区间图,没有长为 3 和 5 的环的图。
  • 在线 k k k 分图染色,给出了 O ( k 2 k n k − 2 k − 1 ( log ⁡ n ) 1 k − 1 ) O(k2^kn^{\frac {k-2}{k-1}}(\log n)^{\frac{1}{k-1}}) O(k2knk1k2(logn)k11) 种颜色的做法。

边染色

如果两条边有公共点,则不能是同一个颜色。
显然下界是 max ⁡ d ( v ) \max d(v) maxd(v),这里给出一个 max ⁡ d ( v ) + 1 \max d(v)+1 maxd(v)+1 种颜色的构造。

  • 构造:一条边一条边加进去,设当前边链接 ( v , w 1 ) (v,w_1) (v,w1),找到没有在 v v v 的出边中出现的颜色 a a a。设 w i w_i wi 中没有出现的最小颜色是 b i b_i bi。若 a = b 1 a=b_1 a=b1,那么就结束了,否则我们从 w 1 w_1 w1 走一条 a , b 1 a,b_1 a,b1 交错的路径。如果这条路的终点不是 v v v,那么我们反一下色。如果是 v v v,那么设倒数第二个点是 w 2 w_2 w2,将 ( v , w 2 ) (v,w_2) (v,w2) 删掉(其颜色为 b 1 b_1 b1),那么此时可以将 ( v , w 1 ) (v,w_1) (v,w1) 染成 b 1 b_1 b1,接下来加入 w 2 w_2 w2
    重复这个过程,当加入 w j w_j wj 时若出现 b j = b i b_j=b_i bj=bi。首先 ( v , w j ) (v,w_j) (v,wj) 原先的颜色是 b j − 1 b_{j-1} bj1,因此 i < j − 1 ii<j1。那么从 w j w_j wj 走交错路径( a , b j a,b_j a,bj)如果要走到 v v v 的话,一定会走到 w i w_i wi。但是从 w i w_i wi 出发的路径到了 w i + 1 w_{i+1} wi+1,所以 w j w_j wj 出发的交错路径不会经过 v v v

平面图染色

四色定理告诉我们,任意一个平面图可以被四染色,但并没有给出构造。
这里可以给出弱化版,五色定理的构造:

  • 构造:首先由 E ≤ V + F − 2 E\le V+F-2 EV+F2(边,点,面),又有一个面至少有 3 条边,一条边只在两个面上,故 F ≤ 2 3 E F\le \frac 23 E F32E,所以 E ≤ 3 V − 6 E\le 3V-6 E3V6,故一定存在一个度数 ≤ 5 \le 5 5 的点。
    找到一个度数 ≤ 5 \le 5 5 的点,对剩下的 5 染色,若度数 < 5 <5 <5 那么合法,下面讨论度数为 5 的情况。设出去的 5 条边指向的点 a 1 , a 2 , a 3 , a 4 , a 5 a_1,a_2,a_3,a_4,a_5 a1,a2,a3,a4,a5(按顺时针顺序)(不妨设 a i a_i ai 的颜色为 i i i),从 a 1 a_1 a1 找可以通过 1/3 交错路径走到的点的集合 S S S,若 a 3 ∉ S a_3\notin S a3/S 那么换一下颜色即可。对 a 2 , a 4 a_2,a_4 a2,a4 做同样的操作。现在存在 1/3,2/4 的交错路径,容易发现这两条路径一定相交,不符合平面图。所以一定可以找到一组并反色。

离线三分图染色

朴素算法:对于度数较大的点 v v v,由于 N ( v ) N(v) N(v) 是二分图,用两种颜色就可以将这些点删去,对于剩下的度数较小的点,直接贪心染色。颜色数 2 n B + B = O ( n ) 2\frac nB+B=O(\sqrt n) 2Bn+B=O(n )

论文接着给出了一个 O ( n 2 / 5 ) O(n^{2/5}) O(n2/5) 种颜色的做法。
我并没有学会 /kk,它的大概思路如下:先设我们可以找到一个 O ( f ( n ) ) O(f(n)) O(f(n)) 种颜色的多项式做法(设 f ( n ) = n α ( log ⁡ n ) β f(n)=n^{\alpha}(\log n)^{\beta} f(n)=nα(logn)β)。
那么若我们找到如下进展的任意一个:

  • 进展1:找到点集 V 1 V_1 V1,使得 V 1 V_1 V1 的导出子图是二分图,且 ∣ V 1 ∣ = Ω ( n / f ( n ) ) |V_1|=\Omega (n/f(n)) V1=Ω(n/f(n))
  • 进展2:找到点集 V 2 V_2 V2,使得 V 2 V_2 V2 的导出子图是二分图,且 N ( V 2 ) = O ( ∣ V 2 ∣ f ( n ) ) N(V_2)=O(|V_2|f(n)) N(V2)=O(V2f(n))
  • 进展3:找到 u , v u,v u,v,在任意一种三染色方案中,它们同色。

进展 2 的意义是,把 V 2 V_2 V2 中的点染色,然后将它们的邻点删掉,要求删掉的点不要太多。
下面,我们来分析找不到任意一个进展的图有什么性质:

  • 首先所有 d ( v ) = Ω ( f ( n ) ) d(v)=\Omega(f(n)) d(v)=Ω(f(n)),否则找到了进展 2。
    接下来对于某一对 u , v u,v u,v,设 S = N ( u ) ∩ N ( v ) S=N(u)\cap N(v) S=N(u)N(v),若 ∣ S ∣ = Ω ( n / f ( n ) 2 ) |S|=\Omega(n/f(n)^2) S=Ω(n/f(n)2),若 N ( S ) N(S) N(S) 是二分图,且 ∣ N ( S ) ∣ ≥ f ( n ) ∣ S ∣ = Ω ( n / f ( n ) ) |N(S)|\ge f(n)|S|=\Omega(n/f(n)) N(S)f(n)S=Ω(n/f(n)) 则找到进展 1,否则 N ( S ) ≤ f ( n ) ∣ S ∣ N(S)\le f(n)|S| N(S)f(n)S 找到了进展 2。
    N ( S ) N(S) N(S) 不是二分图,则 u , v u,v u,v 同色。

现在我们知道,每个点度数是 Ω ( f ( n ) ) \Omega(f(n)) Ω(f(n)) 且任意两个点的公共邻居个数为 O ( n / f ( n ) 2 ) O(n/f(n)^2) O(n/f(n)2)
有了这个性质,因为 N ( N ( v ) ) N(N(v)) N(N(v)) 有相当一部分点和 v v v 同色,所以最小点覆盖不大,通过最小点覆盖的近似算法可以在多项式时间求出不超过最小点覆盖 ( 2 − log ⁡ log ⁡ n 2 log ⁡ n ) (2-\frac{\log \log n}{2\log n}) (22lognloglogn) 被的点覆盖,这样一来,我们就能求出大小可观的最小点覆盖(比较小),所以就有大小可观的最大独立集(比较大)。

对于度数比较接近的情况, N ( N ( v ) ) N(N(v)) N(N(v)) 大概有 1 2 \frac 12 21 的点与 v v v 同色,所以论文对度数进行了分组(需要权衡组数以及每组的点数)。

接着通过神秘分析,可以找到大小 O ( f ( n ) 4 / n log ⁡ 8 n ) O(f(n)^4/n\log^8 n) O(f(n)4/nlog8n) 的独立集 ~
然后平衡得到 O ( n 2 / 5 ) O(n^{2/5}) O(n2/5) 种颜色。

区间图在线染色

区间图指的是每个点代表一个区间,两个点有边当且仅当它们的区间相交。
这里,论文给出了 3 ω ( G ) − 2 3\omega(G)-2 3ω(G)2 种颜色的构造,其中 ω ( G ) \omega(G) ω(G) 是最大团

算法(大概是这样):

  1. 新增一个区间 v v v,求出它和之前所有区间的最大团大小 k k k。(最大团可以表示为 max ⁡ x ( ∑ [ l i ≤ x ≤ r i ] ) \max_x(\sum [l_i\le x\le r_i]) maxx([lixri]))
  2. 对于每个 i i i,维护 G i , S i G_i,S_i Gi,Si,需要保证 ω ( G i ) ≤ i − 1 \omega (G_i)\le i-1 ω(Gi)i1,如果当前来的可以放进 G i G_i Gi,就处理 G i G_i Gi 的问题即可,否则放进 S i S_i Si
  3. S i S_i Si 中的点用不超过 3 中颜色即可染色。这是因为 ω ( G i ) \omega (G_i) ω(Gi) S i S_i Si 中任意一个点的最大团大小都是 i i i,所以对于每个 p ∈ S i p\in S_i pSi,存在 x ∈ [ l p , r p ] , ∑ t ∈ G i [ l t ≤ x ≤ r t ] = i − 1 x\in [l_p,r_p],\sum_{t\in G_i}[l_t\le x\le r_t]=i-1 x[lp,rp],tGi[ltxrt]=i1,所以若存在 p , q ∈ S i , l p ≤ l q ≤ r q ≤ r p p,q\in S_i,l_p\le l_q\le r_q\le r_p p,qSi,lplqrqrp,那么最大团至少是 i + 1 i+1 i+1。所以 S i S_i Si 中的每个点和集合中的点只有两个右边,故用 3 种颜色即可。

代码(在我想象中大概是这样):

void insert(v) {
	int pre = w(G), k = w(G + v);
	if(pre < now) G[k] = G, S[k].insert(i), col[i] = ... ;
	else {
		for(int i = k; i; ) {
			if(i == 1) {
				col[v] = 1;
				break;
			}
			if(w(G[i] + v) <= i - 1) --i;
			else {
				S[i].insert(i), col[i] = ... ; 
				break;
			}
		}
	}
	put v in G 
}

下面,我们可以证明区间图在线染色的颜色下界为 3 ω ( G ) − 2 3\omega(G)-2 3ω(G)2
给出下面这种构造就可以了:

  • 首先对于 ω ( G ) = 1 \omega(G)=1 ω(G)=1,成立。
  • 将一个 ω ( G ) = i \omega(G)=i ω(G)=i,用了 3 i − 2 3i-2 3i2 种颜色的图看成一个点,并将这个点在数轴上重复 5 次,依次设为 a , b , c , d , e a,b,c,d,e a,b,c,d,e
  • 放一个区间 1 使得其包含 a a a,再放一个区间 2 包含 e e e
    若它们颜色相同,构造区间 3 与区间 1 相交且包含 b , c b,c b,c,再构造区间 4 与区间 2,3 相交且包含 c c c 即可。
    否则颜色不同,构造区间 3 与区间 1 相交且包含 b b b,构造区间 4 与区间 2 相交且包含 d d d,那么为了不用 3 种颜色,区间 4,1颜色相同,区间 3,2 颜色相同,此时构造区间 5 与 3,4 相交且包含 c c c 即可。

不存在 C 3 C_3 C3 C 5 C_5 C5 的图,在线染色

即没有长为 3 和 5 的简单环的图。
论文给出了使用 2 ⌊ n ⌋ 2\lfloor \sqrt n\rfloor 2n 种颜色的做法。

  • 设阈值 B = ⌊ n ⌋ B=\lfloor\sqrt n\rfloor B=n ,对 B < i ≤ 2 B BB<i2B 维护集合 W i W_i Wi
    当加入一个点 v v v 时,贪心染色,若染不了:
    若存在 W i W_i Wi 满足 v ∈ N ( W i ) v\in N(W_i) vN(Wi),那么将 v v v 染色为 i i i
    否则找到第一个 W i = ∅ W_i=\empty Wi=,将 v v v 染成 i i i,并令 W i = { u ∣ u ∈ N ( v ) , c o l ( u ) ≤ B } W_i=\{u\mid u\in N(v),col(u)\le B\} Wi={uuN(v),col(u)B}
    容易发现 W i ≥ B W_i\ge B WiB W i ∩ W j = ∅ W_i\cap W_j=\empty WiWj=

这个算法的核心是,对于度数较小的点我们可以直接染色,对于度数较大的点单独染色,并且如果一个度数大的点与另一个度数大的点距离只有 2,那它们就可以染同一种颜色(它们直接肯定没有边,不然就有长为 3 或 5 的环)。

二分图,在线染色

首先,从树的情况就可以知道,最坏情况至少使用 o ( log ⁡ n ) o(\log n) o(logn) 种颜色,构造如下:
我们设 T i T_i Ti 表示一棵有 i i i 种颜色的树,那么要构造 T i T_i Ti,只需要在 T 1 , … , T i − 1 T_1,\dots,T_{i-1} T1,,Ti1 中各选一个点,用一个点作为根连向它们即可。容易发现这样构造的话 ∣ T i ∣ = ∑ j < i ∣ T j ∣ + 1 |T_i|=\sum_{jTi=j<iTj+1,即一棵 2 i 2^i 2i 个点的树就可以逼迫我们使用 i i i 种颜色。

论文给出了一个使用 2 log ⁡ n 2\log n 2logn 种颜色的染色方法。

  • 维护每个联通块,设每个联通块的最大颜色为 k i k_i ki,每加入一个点就会合并若干个联通块。
    我们强行要求每个二分图一边没有用过 k i k_i ki,一边没有用过 k i − 1 k_i-1 ki1
    考虑合并两个联通块,最大颜色分别为 k 1 , k 2 k_1,k_2 k1,k2,当 k 2 ≤ k 1 − 2 k_2\le k_1-2 k2k12 时,是不会和第二个连通块冲突的。考虑 k 2 = k 1 − 1 k_2=k_1-1 k2=k11,分类讨论:
    若该点在 k 1 k_1 k1 一侧,则染色为 k 1 k_1 k1,此时和第二个图不会有冲突,新的 k k k 设为 k 1 + 1 k_1+1 k1+1,那么就满足一边没有 k k k,一边没有 k − 1 k-1 k1
    若该点在 k 1 − 1 k_1-1 k11 一侧,则染色为 k 1 + 1 k_1+1 k1+1,同理合法。
    考虑 k 1 = k 2 k_1=k_2 k1=k2 的情况,此时染色为 k 1 + 2 k_1+2 k1+2 是合法的。

f i f_i fi 表示逼迫我们使用 i i i 个颜色的图的最小点数,容易发现 f i = 2 f i − 2 + 1 ≥ 2 i / 2 f_i=2f_{i-2}+1\ge 2^{i/2} fi=2fi2+12i/2,故我们使用的颜色不超过 2 log ⁡ n 2\log n 2logn

K K K 分图,在线染色

注意到对于 k k k 分图,任意一个 N ( v ) N(v) N(v) 满足其为 k − 1 k-1 k1 分图,于是我们可以来划分子问题。
我们可以设定一个阈值 s s s,用 s s s 种颜色贪心染色,考虑没法染色的点集 R R R,设颜色为 i i i 的点的集合为 C i C_i Ci,那么用 ∣ C i ∣ |C_i| Ci 最小的去将 R R R 划分为 ∣ C i ∣ |C_i| Ci 个子问题(也就是不超过 n / s n/s n/s 个子问题)

在线染色的过程中,我们遇到的困难是没法选择最小的 C i C_i Ci,以及不能很好的确定 s s s

我们先考虑 n , k n,k n,k 已知的情况,此时我们可以计算一下 s = S ( n , k ) s=S(n,k) s=S(n,k),同时,我们随机选择 C i C_i Ci
算法 Solve(n,k):输入一个 n n n 个点的 k k k 分图,在线返回方案。

  1. k ≤ 2 k\le 2 k2,使用二分图染色算法。
  2. s = S ( n , k ) s=S(n,k) s=S(n,k),随便选一个 r r r,维护图 G G G
  3. 每次加一个点 v v v,若 v v v 贪心染成功,则加入 G G G。若 v v v 染成了 r r r,则新增 Solve(s,k-1)。
  4. 否则,把 v v v 送到一个 Solve(s,k-1) 里面,如果里面有 s s s 个点,则新增一个 Solve(s,k-1)。

颜色数:
A ( n , k ) A(n,k) A(n,k) 表示期望的最大颜色数,有 A ( n , k ) ≤ k 2 k n k − 2 k − 1 ( log ⁡ n ) 1 k − 1 A(n,k)\le k2^{k}n^{\frac{k-2}{k-1}}(\log n)^{\frac 1{k-1}} A(n,k)k2knk1k2(logn)k11
t i t_i ti 表示 r = i r=i r=i 时的子任务个数,那么有 t i ≤ ∣ C i ∣ + n / s t_i\le |C_i|+n/s tiCi+n/s,于是有:
A ( n , k ) ≤ s + A ( s , k − 1 ) s ∑ i = 1 s t i = s + 2 n s A ( s , k − 1 ) = s + 2 n s 1 k − 2 ( k − 1 ) 2 k − 1 ( log ⁡ n ) 1 k − 2 A(n,k)\le s+\frac {A(s,k-1)}s \sum_{i=1}^s t_i=s+\frac{2n}{s}A(s,k-1)\\=s+\frac {2n}{s^{\frac{1}{k-2}}}(k-1)2^{k-1}(\log n)^{\frac 1{k-2}} A(n,k)s+sA(s,k1)i=1sti=s+s2nA(s,k1)=s+sk212n(k1)2k1(logn)k21
s = 2 k n k − 2 k − 1 ( log ⁡ n ) 1 k − 1 s=2^{k}n^{\frac{k-2}{k-1}}(\log n)^{\frac 1{k-1}} s=2knk1k2(logn)k11
则有 A ( n , k − 1 ) ≤ s + ( k − 1 ) 2 k n k − 2 k − 1 ( log ⁡ n ) 1 k − 1 A(n,k-1)\le s+(k-1)2^kn^{\frac{k-2}{k-1}}(\log n)^{\frac 1{k-1}} A(n,k1)s+(k1)2knk1k2(logn)k11

对于不知道 n , k n,k n,k,我们只需要维护预估的 n ′ , k ′ n',k' n,k,当点数超过 n ′ n' n 时提升两倍。
若执行到 Solve(n,2) 发现不是二分图,只需要将 k ′ k' k 加 1 即可。

你可能感兴趣的:(算法)