题目大意$ ewcommand{SD}{mathrm{SD}}$
给定一个 $n+1$ 个点的有向无环图,点从 $0$ 开始编号。无重边、自环,且从每个点 $u$ 都能到达 $0$ 号点。如果每条 $uleadsto 0$ 路径($u e 0$)都经过点 $v$ ($v e 0$ 且 $v e u$),则称 $u$ 不稳定,否则称 $u$ 稳定。求稳定点的个数。
一个错误解法
先记录我的一个错误做法。将输入的图中的边全部反向,从 $0$ 号点开始 DFS。有向无环图在 DFS 的过程中不会出现回边(backward edge,也译作「后向边」),只有树边、前向边(forward edge)和侧向边(cross edge,也译作「横叉边」)。点 $u$ 稳定等价于「存在两条点不相交的 $0leadsto u$ 路径」。而这个条件要是满足,那么必然出现连向 $u$ 的前向边或侧向边。在 DFS 的过程中,当发现有前向边或侧向边连向 $u$ 时,就检查当前这条 $0leadsto u$ 路径和之前找到的完全由树边构成 $0leadsto u$ 路径是否交叉,若无交叉,则 $u$ 稳定。可以通过类似 Tarjan 离线 LCA 算法的思路来判断上述两路径是否交叉,只要判断 $u$ 和 $0$ 是否在一个集合中(并查集),若在同一个集合中则无交叉。
代码:
#include <bits/stdc++.h>
#define rep(n) for(size_t __i = 0, __j=(n); __i < __j; ++__i)
#define rep2(i,n) for(size_t (i)=0, _i=n;(i)<_i;(i)++)
#define rep3(i,b,e) for(size_t i =(b); (i)<(e); (i)++)
#define ran(i,b,e) for(size_t (i)=(b); (i)<(e); (i)++)
#define drep2(i,n) for(size_t (i)=(n)-1; (i)>=0; (i)--)
using namespace std;
using ll=long long;
const size_t N=size_t(1e5+5);
vector<size_t> g[N];
bool is_stable[N];
size_t fa[N];
size_t root(size_t x){
return x==fa[x]?x:fa[x]=root(fa[x]);
}
void unite(size_t x, size_t y){
x=root(x);
y=root(y);
fa[x]=y;
}
bool vis[N];
void dfs(size_t u){
vis[u]=true;
for(auto v:g[u]) {
if (!vis[v]){
dfs(v);
unite(v,u);
}
else if (root(v) == 0) is_stable[v] = true;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
size_t n;
cin>>n;
ran(i,1,n){
fa[i]=i; // init
size_t k;
cin>>k;
rep(k){
size_t x;
cin>>x;
g[x].push_back(i);
}
}
dfs(0);
for(auto x:g[0]) is_stable[x]=true;
int ans=0;
ran(i,1,n) ans+=is_stable[i];
cout<<ans<<'
';
return 0;
}
这个做法是错的,下面给出一个反例:
节点编号也是节点的访问顺序。这个做法将 $3$ 号节点判为不稳定的。
题解上的做法
这道题我没想出正解。
仍考虑输入的图。
如果每条 $uleadsto 0$ 路径($u
e 0$)都经过 $v$ ($v
e 0$ 且 $v
e u$),则称 $v$ 是 $u$ 的支配点(dominator)。若 $v$ 是 $u$ 的支配点且 $v$ 是稳定的,则称 $v$ 为 $u$ 的稳定支配点(stable dominator)。
不难证明,支配点有下述性质:
性质 1
$u$ 的支配点可能不唯一,但一定分布在某条链上。
这个性质根据定义很容易证明。
性质 2
设 $v_1$、$v_2$ 是 $u$ 的两个支配点,那么或者 $v_1$ 是 $v_2$ 的支配点,或者 $v_2$ 是 $v_1$ 的支配点。
证明:
不失一般性,假设存在路径 $Pcolon uleadsto v_1leadsto v_2leadsto 0$ ,则必有 $v_2$ 是 $v_1$ 的支配点。若不然,即存在路径 $P'colon v_1leadsto 0$ 满足 $v_2$ 不在 $P'$ 上,从而 $v_2$ 也不是 $u$ 的支配点。
性质 3
若 $u$ 是不稳定的,则 $u$ 有唯一的稳定支配点。
证明:
用 $d(u)$ 表示 $u$ 到 $0$ 的最短距离。满足 $d(v)=1$ 的点 $v$ 必定是稳定的。
若 $v$ 是 $u$ 的支配点则必有 $d(v) < d(u)$ 。
由于 $u$ 的支配点的支配点也是 $u$ 的支配点,所以 $u$ 的稳定支配点必然存在。
$u$ 的稳定支配点是 $u$ 的所有支配点中距离 $0$ 号点最近的那个点。
又根据性质 $2$ 可知 $u$ 的稳定支配点唯一。
若 $u$ 不稳定,用 $SD(u)$ 表示 $u$ 的稳定支配点。
可以证明下述定理
定理 1
$u e 0$ 是稳定的当且仅当:
(1) 存在弧 $(u,0)$;或者
(2) 存在两条「点(除 $u$ 外)不相交」的路径 $uleadsto v_1$ 和 $uleadsto v_2$ 满足 $v_1$ 和 $v_2$ 都是稳定的。
必要性是显然的,条件(2)的充分性也很容易证明。
若图中存在 $uleadsto v$ 路径则称 $v$ 为 $u$ 的后继(successor),若图中存在弧 $(u,v)$ 则称 $v$ 为 $u$ 的直接后继(direct successor)。
具体实现就是:将图上的点拓扑排序,按照拓扑排序的逆顺序依次(根据定理 1)判断每个点是否稳定。定理 1 中的第二个条件中的 $v_1$、$v_2$ 包括:
- $u$ 的稳定直接后继,
- $SD(v)$:$v$ 是 $u$ 的不稳定直接后继。
下面证明
性质 4
设 $v_1$、$v_2$ 是 $u$ 的两个不稳定的直接后继。若 $SD(v_1) e SD(v_2)$,则存在两条点不相交的路径 $v_1leadsto SD(v_1)$ 和 $v_2leadsto SD(v_2)$ 。
证明:
反证法。
设 $P_1$ 是某一条 $v_1leadsto SD(v_1)$ 路径,令 $P_2$ 是任意一条 $v_2 leadsto SD(v_2)$ 路径,将路径 $P_1$、$P_2$ 上点的交集记作 $V$($V
e emptyset$),将 $V$ 中「拓扑序最小的点」和「拓扑序最大的点」分别记为 $s(V)$ 和 $t(V)$ 。由于 $SD(v_1)$ 是 $v_1$ 的支配点,可知 $SD(v_1)in V$,否则路径 $v_1 xrightarrow{P_1} s(V)xrightarrow{P_2} t(V) xrightarrow{P_2} SD(v_2)leadsto 0$ 是一条不经过 $SD(v_1)$ 的路径,这与 $SD(v_1)$ 是 $v_1$ 的支配点矛盾!故 $P_2$ 经过点 $SD(v_1)$ 。$P_2$ 是任意选取的,因而 $SD(v_1)
e SD(v_2)$ 也是 $v_2$ 的稳定支配点,这又与性质 3 矛盾!所以假设不成立。
图中绿色路径表示 $P_1$,蓝色路径表示 $P_2$ 。
上述证明中有一个不严密的地方,即 $SD(v_2)leadsto 0$ 路径可能与 $P_1$ 相交;下面加以完善。
假设任意 $SD(v_2)leadsto 0$ 路径都与路径 $P_1$ 有交点;由于 $SD(v_2)$ 是稳定的,存在一条不经过点 $SD(v_1)$ 的 $SD(v_2)leadsto 0$ 路径 $P^*$,设 $w
eSD(v_1)$ 是 $P_1$ 与 $P^*$ 的一个交点,则 $v_1xrightarrow{P_1} wxrightarrow{P^*} 0$ 也是一条不经过 $SD(v_1)$ 的路径,同样可导出矛盾。另外,容易证明,任意 $SD(v_2)leadsto 0$ 路径与 $P_2$ 都没有除 $SD(v_2)$ 以外的交点。