问题:
给你一个有向图,求出对于每一个点
x
x
x,删去哪些
y
y
y 过后任然与
S
S
S 联通
支配树:
构造出一棵树,以
S
S
S 为根,一个点所有的删去
y
y
y 使它与
S
S
S 不连通的就是它到根路径上的所有点
求法:
定义
i
d
o
m
[
x
]
idom[x]
idom[x] 表示能支配
x
x
x 的最深的点
s
e
m
i
[
x
]
semi[x]
semi[x] 为
x
x
x 的半支配点
众所周知,一般的图很烦的时候应该先
d
f
s
dfs
dfs 出一棵树,考虑
d
f
s
dfs
dfs 序以及非树边
我们令
d
f
n
[
x
]
dfn[x]
dfn[x] 为
x
x
x 的
d
f
s
dfs
dfs 序
s
e
m
i
[
x
]
semi[x]
semi[x] 的定义如下:
m
i
n
{
v
∣
p
a
t
h
(
v
0
,
v
1
,
v
2
,
.
.
.
,
v
k
)
,
v
k
=
x
,
∀
i
∈
[
1
,
k
−
1
]
,
d
f
n
[
v
i
]
>
d
f
n
[
x
]
}
min\{v|path(v_0,v_1,v_2,...,v_k),v_k=x,\forall i\in[1,k-1],dfn[v_i]>dfn[x]\}
min{v∣path(v0,v1,v2,...,vk),vk=x,∀i∈[1,k−1],dfn[vi]>dfn[x]}
去头去尾,都走
d
f
n
dfn
dfn 大于
x
x
x 的点
如果中间没有点,那么
s
e
m
i
[
x
]
=
f
a
[
x
]
semi[x]=fa[x]
semi[x]=fa[x]
s e m i [ x ] semi[x] semi[x] 的性质:
- 一个点的半支配点只可能是它在 d f s dfs dfs 树上的祖先
- 一个点的支配点 i d o m [ x ] idom[x] idom[x] 一定出现在 s e m i [ x ] semi[x] semi[x] 到根的链上
s
e
m
i
[
x
]
semi[x]
semi[x] 推
i
d
o
m
[
x
]
idom[x]
idom[x]
在路径
s
e
m
i
[
x
]
,
x
semi[x],x
semi[x],x 上找到一个
z
z
z 使得
s
e
m
i
[
z
]
semi[z]
semi[z] 最小
如果
s
e
m
i
[
z
]
=
s
e
m
i
[
x
]
semi[z]=semi[x]
semi[z]=semi[x] 那么
i
d
o
m
[
x
]
=
s
e
m
i
[
x
]
idom[x]=semi[x]
idom[x]=semi[x]
否则
i
d
o
m
[
x
]
=
i
d
o
m
[
z
]
idom[x]=idom[z]
idom[x]=idom[z]
感性理解:
第一种情况就是整条链都上不去了
第二种就是如果支配点不是
i
d
o
m
[
z
]
idom[z]
idom[z],那么一定可以通过
i
d
o
m
[
z
]
idom[z]
idom[z] 走到
z
z
z 到
x
x
x
实现:
考虑到
s
e
m
i
semi
semi 的定义,我们按
d
f
n
dfn
dfn 从大到小做
s
e
m
i
[
x
]
=
m
i
n
{
s
e
m
i
[
z
]
}
semi[x]=min\{semi[z]\}
semi[x]=min{semi[z]} z 经过
d
f
n
>
d
f
n
[
x
]
dfn>dfn[x]
dfn>dfn[x] 的边到 x
枚举可以到
x
x
x 的点
y
y
y,然后就是
y
y
y 向上的一条链的
s
e
m
i
[
z
]
semi[z]
semi[z] 的最小的那一个
带权并查集维护,之前合并的都是
d
f
n
>
d
f
n
[
x
]
dfn>dfn[x]
dfn>dfn[x] 的点
求
i
d
o
m
[
x
]
idom[x]
idom[x],直接考虑对每一个
x
x
x 求它作为
s
e
m
i
semi
semi 的所有点的
i
d
o
m
idom
idom