强连通分量

有向图中,若对于图中任意节点 \(x,y\) ,既存在 \(x\)\(y\) 的路径,也存在 \(y\)\(x\) 的路径,则该图是强连通图。
强连通分量是有向图的极大强连通子图。

求出一个有向图的强连通分量:

用 dfs 遍历图,访问到一个节点就把该节点入栈,并记录时间戳。
定义一个点的追溯值为满足以下条件节点的最小时间戳:

  1. 点在当前栈内。
  2. 存在一条以当前点子树中的点出发的边以该点为终点。
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:

  1. 可以判断一些特殊的环,比如在边权只有0和1时判断是否存在正环。
  2. 二分图最大匹配的必经边。
posted @ 2021-11-12 11:58  字如其人  阅读(227)  评论(0)    收藏  举报