图论(2)
网络流
- 反向边 — 改变之前的选择,顺便补充新流 / 交换不同流的去向
-
复杂度证明
-
F F FF FF — O ( E m a x v ) O(E\,max\,v) O(Emaxv)
-
E K EK EK/ S A P SAP SAP(最短路增广)— O ( n m 2 ) O(nm^2) O(nm2) :
- 一条边(或其反向边)每满流一次,两次的增广路长度至少多加2:
- 考虑增广路1 s-u-v-t ( d i s = d i s s − u + d i s v − t + 1 \large dis=dis_{s-u}+dis_{v-t}+1 dis=diss−u+disv−t+1),(u,v) 满流;下一次经过 (u,v) 的增广路2 s-v-u-t 中满足 d i s s − v ′ > d i s s − u \large dis'_{s-v}> dis_{s-u} diss−v′>diss−u 与 d i s u − t ′ > d i s v − t \large dis'_{u-t}> dis_{v-t} disu−t′>disv−t(否则 增广路1 不满足最短路增广),则有 d i s ′ = d i s s − v ′ + d i s u − t ′ + 1 ≥ d i s + 2 \large dis'=dis'_{s-v}+dis'_{u-t}+1\geq dis+2 dis′=diss−v′+disu−t′+1≥dis+2. 得证。
- 可得增广路条数 O ( n m ) O(nm) O(nm)。且求一条增广路 O ( m ) O(m) O(m)。
- 一条边(或其反向边)每满流一次,两次的增广路长度至少多加2:
-
d i n i c dinic dinic (多路增广)
-
一般情况: O ( n 2 m ) O(n^2m) O(n2m)
证明:
单轮(多路)增广 O ( n m ) O(nm) O(nm) — 所有当前弧变化总共 O ( m ) O(m) O(m) 次,单次 O ( n ) O(n) O(n).
增广 O ( n ) O(n) O(n) 轮.
- 在边权均为1时, O ( m i n ( n 2 3 , m 1 2 ) ⋅ m ) ≈ O ( n m ) O(min(n^{\frac{2}{3}},m^{\frac{1}{2}})\cdot m)\approx O(nm) O(min(n32,m21)⋅m)≈O(nm)
- 二分图匹配问题 / 边容量都为1、出/入边唯一的单位网络 中 —
O
(
m
n
)
O(m\sqrt n)
O(mn)
- 证明:
- n \sqrt n n 次增广后,随便找一个最大匹配与当前匹配比较(异或),会得出一些环和点不相交链(增广路);不理会环;这些链/增广路的 长度> n \sqrt{n} n,且经过点数 O ( n ) O(n) O(n),故还剩 增广路条数/匹配数 为 O ( n ) O(\sqrt n) O(n) 的;又接下来每次增广必增加匹配数,所以有 O ( n ) O(\sqrt n) O(n) 轮增广。
- 单轮增广 O ( m ) O(m) O(m) — 因为边权都为1,最多每条边经过一次。
- 即可得出结论。
-
-
I S A P ISAP ISAP (将 d i n i c dinic dinic 改用 预处理+距离标号) — 与 d i n i c dinic dinic 类似。
-
预留推进 — O ( n 2 m ) O(n^2m) O(n2m) :每个点改高度标号 O ( n ) O(n) O(n) 次,每次可多增广 O ( m ) O(m) O(m) 次。
- 做法:每次找一个“溢出点”,从某一条未满流边 流向 一个高度恰小1的点;适时修改高度标号。
- 初始化:源点把每条出边流满。
-
H L P P HLPP HLPP(用堆选最高点推进)— O ( n 2 m ) O(n^2\sqrt m) O(n2m) .
-
有无源汇、有无上下界 费用流
(…) gugugu
最小割
-
最大流最小割定理 — 一个流 f 的任意割 cut(S,T) 满足 f 等于正负向割边流量差;最大流中 负向割边流量为0 – 正向的与割取等。 ---- baidu.com
-
无源汇最小割(全局最小割) — 划分点集 的最小删边代价
-
S
t
o
e
r
\bold{Stoer}
Stoer-
W
a
g
n
e
r
\bold{Wagner}
Wagner —
O
(
n
m
+
n
3
)
/
O
(
n
m
+
n
2
log
n
)
O(nm+n^3)/O(nm+n^2\log n)
O(nm+n3)/O(nm+n2logn) 。
-
依据:对于一对点 S,T,要么分居两集(此时 cut(S,T)=cut(G) ),要么两点在最小割同一集合(此时与 若割了(S,u)T 与u必不在同一联通块)。
-
得出做法:1.找到任意一对(S,T)的解。2.将 S、T 合并为一个点,回到步骤1。
-
步骤1:“排序”,使 ( { v 1 , ⋯ , v n − 1 } , { v n } ) (\{v_1,\cdots,v_{n-1}\},\{v_{n}\}) ({v1,⋯,vn−1},{vn}) 为 ( v n − 1 , v n ) (v_{n-1},v_{n}) (vn−1,vn) 最小割 — 任选一点作 v 1 v_1 v1 ,每次找到 f ( V , x ) f(V,x) f(V,x) 最大的 x 加到 V 中。
-
“步骤1”的正确性证明:
设 ( S 1 , S 2 ) o r ( u , v ) d e n o t e s t h e m i n e s t c u t \large (S_1,S_2)or(u,v)\,denotes \,\,the\,\,minest\,\,cut (S1,S2)or(u,v)denotestheminestcut
考虑归纳:归纳条件 – 对于任意图G,“排序”出的前n-1个点满足 — G对这n-1个点的导出子图G’ 中, ( { v 1 , ⋯ , v n − 2 } , { v n − 1 } ) = ( v n − 2 , v n − 1 ) G ′ (\{v_1,\cdots,v_{n-2}\},\{v_{n-1}\})=(v_{n-2},v_{n-1})_{G'} ({v1,⋯,vn−2},{vn−1})=(vn−2,vn−1)G′
对于新加入的 v n v_n vn,由于 ( v n − 1 , v n ) (v_{n-1},v_n) (vn−1,vn) 中一定会割掉两点间的连边,故可先 删去 G中的这些边 得到G’。
设 G n G_n Gn为G’ 对 { v 1 , ⋯ , v n } \{v_1,\cdots,v_n\} {v1,⋯,vn}的导出子图。
首先考虑证明: ( { v 1 , ⋯ , v n − 1 } , { v n } ) ≤ ( v n − 2 , v n ) G n (1) \large \tag1(\{v_1,\cdots,v_{n-1}\},\{v_{n}\})\leq(v_{n-2},v_{n})_{G_n} ({v1,⋯,vn−1},{vn})≤(vn−2,vn)Gn(1)
G’ 对 { v 1 , ⋯ , v n − 2 , v n } \large \{v_1,\cdots,v_{n-2},v_{n}\} {v1,⋯,vn−2,vn}的导出子图A考虑,发现它的“排序”结果与原顺序相同,由归纳条件有:
( { v 1 , ⋯ , v n − 2 } , { v n } ) = ( v n − 2 , v n ) A \large (\{v_1,\cdots,v_{n-2}\},\{v_{n}\})=(v_{n-2},v_{n})_{A} ({v1,⋯,vn−2},{vn})=(vn−2,vn)A
又因 v n − 1 , v n v_{n-1},v_n vn−1,vn间无边,所以可以加入 v n − 1 v_{n-1} vn−1得到图 G n G_n Gn,就有
( { v 1 , ⋯ , v n − 1 } , { v n } ) = ( { v 1 , ⋯ , v n − 2 } , { v n } ) = ( v n − 2 , v n ) A ≤ ( v n − 2 , v n ) G n \large (\{v_1,\cdots,v_{n-1}\},\{v_{n}\})=(\{v_1,\cdots,v_{n-2}\},\{v_{n}\})=(v_{n-2},v_{n})_{A}\leq(v_{n-2},v_n)_{G_n} ({v1,⋯,vn−1},{vn})=({v1,⋯,vn−2},{vn})=(vn−2,vn)A≤(vn−2,vn)Gn然后考虑证明:KaTeX parse error: \tag works only in display equations
由归纳条件有: ( { v 1 , ⋯ , v n − 2 } , { v n − 1 } ) = ( v n − 2 , v n − 1 ) G n − 1 \large (\{v_1,\cdots,v_{n-2}\},\{v_{n-1}\})=(v_{n-2},v_{n-1})_{G_{n-1}} ({v1,⋯,vn−2},{vn−1})=(vn−2,vn−1)Gn−1
由排序条件: ( { v 1 , ⋯ , v n − 2 } , { v n } ) ≤ ( { v 1 , ⋯ , v n − 2 } , { v n − 1 } ) \large (\{v_1,\cdots,v_{n-2}\},\{v_{n}\})\leq(\{v_1,\cdots,v_{n-2}\},\{v_{n-1}\}) ({v1,⋯,vn−2},{vn})≤({v1,⋯,vn−2},{vn−1})
再加入 v n − 1 v_{n-1} vn−1,就有: ( { v 1 , ⋯ , v n − 1 } , { v n } ) = ( ( { v 1 , ⋯ , v n − 2 } , { v n } ) ≤ ( v n − 2 , v n − 1 ) G n − 1 ≤ ( v n − 2 , v n − 1 ) G n \large (\{v_1,\cdots,v_{n-1}\},\{v_{n}\})=((\{v_1,\cdots,v_{n-2}\},\{v_{n}\})\leq(v_{n-2},v_{n-1})_{G_{n-1}}\leq(v_{n-2},v_{n-1})_{G_n} ({v1,⋯,vn−1},{vn})=(({v1,⋯,vn−2},{vn})≤(vn−2,vn−1)Gn−1≤(vn−2,vn−1)Gn
最后引入引理
L e m m a Lemma Lemma:若图G中有三点A,B,C,则有 ( A , B ) G ≥ min { ( A , C ) G , ( B , C ) G } (A,B)_G\geq\min\{(A,C)_G,(B,C)_G\} (A,B)G≥min{(A,C)G,(B,C)G}
证明:
不妨设割最小的一对是 ( A , B ) G (A,B)_G (A,B)G,且C 在这个割中的 B 这一侧,
此时,A,C也被割了(分居割的两集),则
( A , B ) G ≤ ( A , C ) G ≤ ( A , B ) G ⇒ ( A , C ) G = ( A , B ) G (A,B)_G\leq(A,C)_G\leq(A,B)_G\Rightarrow (A,C)_G=(A,B)_G (A,B)G≤(A,C)G≤(A,B)G⇒(A,C)G=(A,B)G
即,三对割中至少有两个最小值。得证。
由引理与 式(1)、式(2),
( { v 1 , ⋯ , v n − 1 } , { v n } ) ≤ min { ( v n − 2 , v n ) G n , ( v n − 2 , v n − 1 ) G n } ≤ ( v n − 1 , v n ) G n \large (\{v_1,\cdots,v_{n-1}\},\{v_{n}\})\leq\min\{(v_{n-2},v_n)_{G_n},(v_{n-2},v_{n-1})_{G_n}\}\leq(v_{n-1},v_n)_{G_n} ({v1,⋯,vn−1},{vn})≤min{(vn−2,vn)Gn,(vn−2,vn−1)Gn}≤(vn−1,vn)Gn
证毕。 -
步骤2:合并 ( v n − 1 , v n ) (v_{n-1},v_{n}) (vn−1,vn) 为一个点,把他们的连边也合并(边权要相加) — 这样,在之后求的最小割中,这两点都会在同一个集合里。
-
复杂度取决于“排序”的复杂度。
-
-
S
t
o
e
r
\bold{Stoer}
Stoer-
W
a
g
n
e
r
\bold{Wagner}
Wagner —
O
(
n
m
+
n
3
)
/
O
(
n
m
+
n
2
log
n
)
O(nm+n^3)/O(nm+n^2\log n)
O(nm+n3)/O(nm+n2logn) 。
竞赛图相关
- 定义:“有向完全图”。
- 性质 ----
- 图结构:强连通分量缩点后构成“链状”结构 — 所有点可以排成一条链,且每个点只向后连边 — 可用往链上不断加点证明。
- 每个至少三个点的强连通分量中三元环存在性:
- 已知存在环,然后对于每个多于三个点的环,加上它的弦会形成规模更小的环,直到没有弦(只剩三个点)。
-
H
a
l
m
i
t
o
n
Halmiton
Halmiton路径存在性 \
H
a
l
m
i
t
o
n
Halmiton
Halmiton回路存在性(为强连通图时):
- 路径 存在性可以用增量法构造。
- 回路 存在性证明:
- 先找到一条H路径 S → T S\rightarrow T S→T,
- 因为强连通,所以必有点 x 向 S 连边, S → x → S S\rightarrow x\rightarrow S S→x→S 构成一个环。
- 考虑路径中下一条边( x → y x\rightarrow y x→y),若 y 向环上有连边,则可并入环中;若连边均指向 y,继续考虑下一条边;
- 由于图强连通,所以一定会出现一个点把环伸出的这条链 x → y → ⋯ x\rightarrow y\rightarrow \cdots x→y→⋯ 并入环中。
- 即可得一条哈密顿回路。
- 分数序列判定(
L
a
n
d
a
u
′
s
T
h
e
o
r
e
m
Landau's \,Theorem
Landau′sTheorem):分数序列(竞赛图中出边表示胜利得分)合法的充要条件:
s
i
≤
s
i
+
1
,
S
k
=
∑
i
≤
k
s
i
≥
(
k
2
)
&
&
S
n
=
(
n
2
)
s_i\leq s_{i+1},S_k=\sum_{i\leq k}s_i\geq\binom{k}{2}\&\& S_n=\binom{n}{2}
si≤si+1,Sk=∑i≤ksi≥(2k)&&Sn=(2n)
- 必要性显然。
- 证明充分性:
- 可以构造一个 s’ ,使得 S k ′ = ( k 2 ) S'_k=\binom{k}{2} Sk′=(2k) — 只要每个点向编号比它小的点连边就行了。
- 然后可以使 v b → v a v_b\rightarrow v_a vb→va 改向为 v a → v b v_a\rightarrow v_b va→vb,则 s a ′ + + , s b ′ − − → S a ⋯ b − 1 + + s'_a++,s'_b--\rightarrow S_{a\cdots b-1}++ sa′++,sb′−−→Sa⋯b−1++
- 可以调整出上述 s.
P r u f e r Prufer Prufer序列
- 定义:对有标号无根树不断摘取编号最小叶节点(剩下两个点),记录下每次删的点的父亲节点得到的长 n − 2 n-2 n−2 的序列即 P r u f e r Prufer Prufer序列。
- 构造:
- 堆 - O ( n log n ) O(n\log n) O(nlogn);单指针扫 O ( n ) O(n) O(n)。
- “翻译”:
- 每次确定一个叶节点。
- 复杂度及分析同“构造”。
- 性质:
- P r u f e r Prufer Prufer序列与有标号无根树建立了双射。
- 点编号在序列中的出现次数 = 树中点度数 - 1.
- 应用:
- 有标号无根树 计数: n n − 2 n^{n-2} nn−2
- 图联通计数: n k − 2 ∏ i = 1 k s i n^{k-2}\prod_{i=1}^k s_i nk−2∏i=1ksi
矩阵树定理
-
D e f i n i t i o n Definition Definition:
- D D D、 D i n D^{in} Din、 D o u t D^{out} Dout 为图的度数矩阵; A A A 为图的边权矩阵。
- L L L、 L i n L^{in} Lin、 L o u t L^{out} Lout 为图的 Laplace 矩阵(亦称 Kirchhoff 矩阵)— L = D − A L=D-A L=D−A
- 生成树个数 t ( G ) t(G) t(G)
- M 0 M_0 M0 为 M M M 去掉一行得到的矩阵。
- 设 M M M为 n × m n\times m n×m 的矩阵。 M [ S ] M[S] M[S] 为,任取大小为 n 的集合 S ( ⊆ [ 1 , m ] ⋂ Z ) S(\subseteq [1,m]\bigcap Z) S(⊆[1,m]⋂Z),保留 M 的第 S i S_i Si 列得到的矩阵( n × n n\times n n×n)。
- L 0 L_0 L0 为 L L L 去掉 i 行 i 列得到的矩阵。
-
M a t r i x − t r e e T h e o r e m Matrix-tree \,\, Theorem Matrix−treeTheorem:
-
无向图: t ( G ) = det ( L 0 ) t(G)=\det(L_0) t(G)=det(L0).
-
证明思路:
-
首先,构造矩阵 M M M — n × m n\times m n×m , M i , j = [ e j = ( i , v ) ] − [ e j = ( u , i ) ] M_{i,j}=[e_j=(i,v)]-[e_j=(u,i)] Mi,j=[ej=(i,v)]−[ej=(u,i)].
有 M M T = L MM^T=L MMT=L.
然后,可以发现 det ( M 0 [ S ] ) = ± [ S 为 某 生 成 树 边 集 ] \large\det(M_0[S])=\pm[S为某生成树边集] det(M0[S])=±[S为某生成树边集]
最后,由 B i n e t − C a u c h y \bold{Binet}\!-\!\bold{Cauchy} Binet−Cauchy定理
det ( L 0 ) = ∑ S det ( M 0 [ S ] ) ⋅ det ( M 0 [ S ] T ) = t ( G ) \large\det(L_0)=\sum_S\det(M_0[S])\cdot\det(M_0[S]^T)=t(G) det(L0)=S∑det(M0[S])⋅det(M0[S]T)=t(G)
-
-
有向图:根向树, t ( G ) = det ( L 0 o u t ) t(G)=\det(L^{out}_0) t(G)=det(L0out);叶向树, t ( G ) = det ( L 0 i n ) t(G)=\det(L_0^{in}) t(G)=det(L0in) 。
-
根向树形式证明思路(与无向类似)(叶向树同理):
-
首先,构造矩阵 A , B A,B A,B, A i , j = [ e j = ( i , v ) ] − [ e j = ( u , i ) ] A_{i,j}=[e_j=(i,v)]-[e_j=(u,i)] Ai,j=[ej=(i,v)]−[ej=(u,i)], B i , j = [ e j = ( i , v ) ] B_{i,j}=[e_j=(i,v)] Bi,j=[ej=(i,v)].
有 A B T = L o u t AB^T=L^{out} ABT=Lout.
然后,可以发现,若 S 为某生成树边集, det ( A 0 [ S ] ) = det ( B 0 [ S ] ) \det(A_0[S])=\det(B_0[S]) det(A0[S])=det(B0[S]);
否则 det ( A 0 [ S ] ) ⋅ det ( B 0 [ S ] ) = 0 \det(A_0[S])\cdot\det(B_0[S])=0 det(A0[S])⋅det(B0[S])=0
最后,
det ( L 0 o u t ) = ∑ S det ( A 0 [ S ] ) ⋅ det ( B 0 [ S ] T ) = t ( G ) \large\det(L_0^{out})=\sum_S\det(A_0[S])\cdot\det(B_0[S]^T)=t(G) det(L0out)=S∑det(A0[S])⋅det(B0[S]T)=t(G)
-
-
拓展:把边权看作重边数,那么可以计算所有生成树的边权积的和 — 可用乘法原理理解。
-
关于 B i n e t − C a u c h y \bold{Binet}\!-\!\bold{Cauchy} Binet−Cauchy定理 的证明:
-
如果有基础结论: ∀ A , B , C ∈ { n-order m a t r i x e s } , det ( C ) = det ( A ) ⋅ det ( B ) \large \forall A,B,C\in\{\text{n-order} \, matrixes\},\det(C)=\det(A)\cdot\det(B) ∀A,B,C∈{n-ordermatrixes},det(C)=det(A)⋅det(B)
那么然后展开定理的式子
左式:
det ( C ) = ∑ P ( − 1 ) λ ( P ) ∏ i C i , P i = ∑ P ( − 1 ) λ ( P ) ∏ i ∑ A i , k ⋅ B k , P i = ∑ P ( − 1 ) λ ( P ) ∑ S ∏ i A i , S i ⋅ B S i , P i ( ∣ S ∣ = n , S i ∈ [ 1 , m ] ) = ∑ P ( − 1 ) λ ( P ) ∑ S ∏ i A i , S i ⋅ B S i , P i ( ∣ S ∣ = n , S i ∈ [ 1 , m ] , ∀ i , j , S i ≠ S j ) \large\det(C)=\large \sum_{P}(-1)^{\lambda(P)}\prod_{i}C_{i,P_i}\\ =\large \sum_{P}(-1)^{\lambda(P)}\prod_{i}\sum A_{i,k}\cdot B_{k,P_i}\\ =\large \sum_{P}(-1)^{\lambda(P)}\sum_{S}\prod_{i} A_{i,S_i}\cdot B_{S_i,P_i}(|S|=n,S_i\in[1,m])\\ =\large \sum_{P}(-1)^{\lambda(P)}\sum_{S}\prod_{i} A_{i,S_i}\cdot B_{S_i,P_i}(|S|=n,S_i\in[1,m],\forall i,j,S_i\neq S_j) det(C)=P∑(−1)λ(P)i∏Ci,Pi=P∑(−1)λ(P)i∏∑Ai,k⋅Bk,Pi=P∑(−1)λ(P)S∑i∏Ai,Si⋅BSi,Pi(∣S∣=n,Si∈[1,m])=P∑(−1)λ(P)S∑i∏Ai,Si⋅BSi,Pi(∣S∣=n,Si∈[1,m],∀i,j,Si=Sj)
右式:
∑ S det ( A [ S ] ) det ( B [ S ] T ) = ∑ S det ( A [ S ] × B [ S ] T ) = ∑ S ∑ P ( − 1 ) λ ( P ) ∏ i ∑ k A [ S ] i , k ⋅ B [ S ] k , P i T = ∑ S ∑ P ( − 1 ) λ ( P ) ∑ Q ∏ i A [ S ] i , Q i ⋅ B [ S ] Q i , P i T = ∑ S ∑ Q ∑ P ( − 1 ) λ ( P ) ∏ i A i , S Q i ⋅ B S Q i , P i T = ∑ S ∑ P ( − 1 ) λ ( P ) ∏ i A i , S i ⋅ B S i , P i T ( ∣ S ∣ = n , S i ∈ [ 1 , m ] , ∀ i , j , S i ≠ S j ) \large\sum_{S}\det(A[S])\det(B[S]^T)=\large\sum_{S}\det(A[S]\times B[S]^T)\\ =\large \sum_{S}\sum_{P}(-1)^{\lambda(P)}\prod_{i}\sum_{k}A[S]_{i,k}\cdot B[S]^T_{k,P_i}\\ =\large \sum_{S}\sum_{P}(-1)^{\lambda(P)}\sum_{Q}\prod_{i}A[S]_{i,Q_i}\cdot B[S]^T_{Q_i,P_i}\\ =\large \sum_{S}\sum_{Q}\sum_{P}(-1)^{\lambda(P)}\prod_{i}A_{i,S_{Q_i}}\cdot B^T_{S_{Q_i},P_i}\\ =\large \sum_{S}\sum_{P}(-1)^{\lambda(P)}\prod_{i}A_{i,S_{i}}\cdot B^T_{S_{i},P_i}(|S|=n,S_i\in[1,m],\forall i,j,S_i\neq S_j) S∑det(A[S])det(B[S]T)=S∑det(A[S]×B[S]T)=S∑P∑(−1)λ(P)i∏k∑A[S]i,k⋅B[S]k,PiT=S∑P∑(−1)λ(P)Q∑i∏A[S]i,Qi⋅B[S]Qi,PiT=S∑Q∑P∑(−1)λ(P)i∏Ai,SQi⋅BSQi,PiT=S∑P∑(−1)λ(P)i∏Ai,Si⋅BSi,PiT(∣S∣=n,Si∈[1,m],∀i,j,Si=Sj)
基础结论也可通过上面的方法展开证明,区别只在于少了S的循环过程。
-
-
-
应用:
- 除了简单的生成树计数,其实还可以把上述拓展应用于“多项式边权”,同样合法。
- 这有什么作用呢?可参考 「2020联合省选Day2T3作业题」 — 这道题把边权设置为 A i x + 1 A_ix+1 Aix+1 ,那么行列式算出来一次项系数便为生成树边权和。
- 另外,结合生成函数的特点,可以发现这个应用的更深层意义 — 幂指数标示了特殊边的选择次数。那么对有关有色边的生成树问题提供了较好的思路。当有多种颜色(
真是变态),就可以考虑多设几个变量 x,y,z,…
BEST定理
欧拉图上的欧拉回路计数。
∀
k
,
a
n
s
=
t
r
o
o
t
(
G
,
k
)
deg
(
k
)
∏
v
∈
V
(
deg
(
v
)
−
1
)
!
\large \forall k, ans=t^{root}(G,k)\deg(k)\prod_{v\in V}(\deg(v)-1)!
∀k,ans=troot(G,k)deg(k)v∈V∏(deg(v)−1)!
为什么呢?首先我们考虑图的任意一棵根向树,对于再每个节点我们将以 u 为起点的所有不在根向树上的 deg u − 1 \deg_u−1 degu−1 条出边(当然如果 u 为根节点就有 deg u \deg_u degu 条不在根向树上的出边)钦定一个走的顺序(最后再走在根向树上的边),方便起见我们称这个根向树及这个出边的排列顺序为一个 “组合” 。
显然证明上式我们只需证明一下两个部分:1.一个 “组合” 唯一对应一条欧拉回路。2.一条欧拉回路唯一对应一个 “组合”。
1.按照 “组合” 的顺序走到根停止时,不存在 边/点未经过 — 树上指向根的边都遍历过,故这些子节点的出边已经走完,可以推到下一层也都满足“走完”,直到所有点/边都判定为遍历过。
2.记录下欧拉回路中除了根的每个点走的最后一条出边,这些边构成一棵根向树 — 出度都为1,故“不成树,即成环”;从环上一点出发,则到走到下一个点时,与这个点的连边已经走完了,与会回到该点矛盾,故“不成环”。
树分治
边分治就不讲了(不知它有什么用),有兴趣自己去了解一下。
- 点分治(多路径计数问题大杀器,或是有关两点距离关系的计数问题)
- 思路:每次找到树重心 x,然后 “处理” 经过 x 的路径;再去掉 x ,对子树分治下去。
- “处理” 是将 两条一端在子树、一端在x 的路径 合并为 “经过 x 的路径”。
- 整个 “处理” 过程的传统思路有两种:
- 1.按顺序处理每棵子树 — 计算 当前子树 与 已处理子树 的贡献;再把 当前子树信息 与 之前的信息 合并。
- 2.去重 — 先把 所有 x 到子树的路径 “无脑合并”(不论路径是否有重边);然后对每个子树,减去在同一子树内“无脑合并”的贡献,即去重。
- 点分树 — 将 x 与每个分治子树的重心 两边,构成一棵树
T
T
T。
- 有什么用?
- 可以发现
T
T
T 是与上述点分治过程息息相关的结构,故 我们可以用
T
T
T 来分析 点分治的复杂度
或是将它的分治过程与整体联系起来(怪怪的) - 经过简单分析,可以发现一些性质
- T T T 的深度不超过 log
- T T T 的子树和为 O ( n log n ) O(n\log n) O(nlogn),可以说明点分治的复杂度。从而,若每层分治需要排序之类的带log操作,复杂度为 O ( n log n ) O(n\log n) O(nlogn)。
- 它最重要的作用还是在于“与分治过程的联系”:
- 发现对于每个点 x ,分治时经过它的路径,会被在它点分树上每个祖先代表的分治层计算。
- 那么如果不是处理全局路径,而是对以 x 为端点的路径进行计算,就可以在点分树祖先处查询(祖先个数是 O ( log ) O(\log) O(log)的)。
- 它还有特殊优势 — 解决带修问题 (动态树分治):
- 思路是,记录下每层分治的信息,对每次修改,维护分治信息的变化 并 考虑它对每层合并的贡献的影响。
- 一般需要 可删堆 或 权值线段树 维护。
树同构相关
-
有 A H U AHU AHU算法 与 树哈希 两种判定方式。
-
A H U AHU AHU算法 — 正确性严格保证。
- 用于有根树,而无根树判定可以通过 定重心为根 转化为有根树同构判定。
- 思路是对树的括号序进行调整再比较。比如,用最小字典序括号序比较。但我们无法承担字符串的存储与比较的代价,所以我们需要 用数“代表”括号序。
-
树哈希 — 方便快捷,便于处理多树同构判定,做有根树判定。
f n o w = s i z n o w × ∑ f s o n ( n o w , i ) × s e e d i − 1 f n o w = ⨁ f s o n ( n o w , i ) × s e e d + s i z s o n ( n o w , i ) f n o w = 1 + ∑ f s o n ( n o w , i ) × p r i m e ( s i z s o n ( n o w , i ) ) \large f_{now}=siz_{now}\times\sum f_{son(now,i)}\times seed^{i-1}\\ \large f_{now}=\bigoplus f_{son(now,i)}\times seed+siz_{son(now,i)}\\ \large f_{now}=1+\sum f_{son(now,i)}\times prime(siz_{son(now,i)}) fnow=siznow×∑fson(now,i)×seedi−1fnow=⨁fson(now,i)×seed+sizson(now,i)fnow=1+∑fson(now,i)×prime(sizson(now,i))
- 第一种方法需排序;第二种容易因同构子树出现次数同奇偶出错;第三种应该挺强的。