强连通分量
有向图中,若对于图中任意节点 \(x,y\) ,既存在 \(x\) 到 \(y\) 的路径,也存在 \(y\) 到 \(x\) 的路径,则该图是强连通图。
强连通分量是有向图的极大强连通子图。
求出一个有向图的强连通分量:
用 dfs 遍历图,访问到一个节点就把该节点入栈,并记录时间戳。
定义一个点的追溯值为满足以下条件节点的最小时间戳:
- 点在当前栈内。
- 存在一条以当前点子树中的点出发的边以该点为终点。
dfn[x]=low[x]=++gpc;
for(int i=head[x];i;i=nxt[i]){
if(!dfn[ver[i]]){
//递归
low[x]=min(low[x],low[ver[i]]);
}
else if(ins[ver[i]])low[x]=min(low[x],dfn[ver[i]]);
}
//此处为处理最后一条链
(\(ins_x\) 记录 \(x\) 是否在栈内,\(dfn_x\) 表示 \(x\) 的时间戳,\(low_x\) 表示 \(x\) 的追溯值)
结论:递归回溯时,若 \(dfn_x=low_x\),则从栈顶到 \(x\) 的节点构成一个强连通分量。(求出强连通分量后把强连通分量中的点弹出)
证明:
考虑数学归纳法,一个点显然是强连通图,若有一个大小为 \(i\) 的强连通图 \(G\),若 \(x\in G\),且边 \((x,y)(y\not\in G)\),(条件1)
只要存在边 \((y,z)(z\in G)\),则 $G\and y $ 也是一个强连通图。(条件2)
由于是栈顶到 \(x\) 间的节点,所以满足条件1;
由于栈顶到 \(x\) 间的点追溯值和时间戳均不相等(不包括 \(x\))且 \(dfn_x=low_x\),所以满足条件2。
所以栈顶到 \(x\) 的节点构成一个强连通图。
同样因为 \(dfn_x=low_x\),所以这些点和其他的点间没有连边,即不会形成环,所以这个子图是极大的强连通图,即强连通分量。
void tarjan(int x){
dfn[x]=low[x]=++gpc;
sta[++top]=x,ins[x]=1;
for(int i=head[x];i;i=nxt[i]){
if(!dfn[ver[i]]){
tarjan(ver[i]);
low[x]=min(low[x],low[ver[i]]);
}
else if(ins[ver[i]])low[x]=min(low[x],dfn[ver[i]]);
}
if(low[x]==dfn[x]){
cnt++;int y;
do{
y=sta[top--],ins[y]=0,c[x]=cnt;
}while(x!=y);
}
}
求出强连通分量后,可以将一个强连通分量视作一个节点,易得这样的图一定是一个有向无环图。
P3387 【模板】缩点
模板,求出强连通分量并缩点后,图变为一个 DAG,一个强连通分量的贡献为分量中点权之和。
按拓扑序 DP 即可。
P2272 [ZJOI2007]最大半连通子图
模板,求出强连通分量并缩点后,图变为一个 DAG,易得此时的最大半连通子图是图中的最长链。
按拓扑序 DP 即可。
P2746 [USACO5.3]校园网Network of Schools
模板,求出强连通分量并缩点。
对于入度不为一的点,若其他点都被覆盖,那它也一定会被覆盖,所以第一问答案为入度为0的点的个数。
对于第二问,所有点的入度和出度都不能为0,所以答案为 \(\max(p,q)\) 。( \(p\) 个入度为0的点, \(q\) 个出度为0的点)
P1407 [国家集训队]稳定婚姻
情人之间男向女连边,夫妻之间女向男连边;
考虑断开一个强连通分量中的一对夫妻,他们在强连通分量内可以重新分配,这样一个强连通分量内的夫妻一定不安全。
Tricks:
- 可以判断一些特殊的环,比如在边权只有0和1时判断是否存在正环。
- 二分图最大匹配的必经边。

浙公网安备 33010602011771号