无向图的强连通分量拓扑

首先先讲一下拓扑排序的递归做法。

看似有点玄学,讲一下为什么是正确的,在一张拓扑图,我们如果能够保证每一条边 a−−−>ba ---> ba>b,在序列中aaa 始终保证在bbb 的前边,那么这个序列一定是拓扑序。贴一下dfsdfsdfs求拓扑的代码:

bool dfs(int x)
{
    vis[x] = true, st[x]= true; //st 数组表示的是点是否遍历到,vis数组则表达的是点是否在正在搜索 dfs 路径上。seq 倒序输出就是答案
    for (int i = h[x]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (vis[j]) return false;
        if (st[j]) continue;
        if (!dfs(j)) return false;
    }
    seq[cnt ++] = x;
    vis[x] = false;
    return true;
}

我们在遍历的时候假设之前bbb没有遍历到,那么我们的bbb 一定是在aaa 前边的,如果是已经遍历过了,那么bbb也是在aaa前边,在倒序的输出下就变成了aaabbb的前边,这里可以简单的思考下。

根据这个算法的启发,我们的tarjantarjantarjan算法的目的是将一个有向图转变成一个有向无环图,也就相当于拓扑图,tarjantarjantarjan算法需要处理横叉边和后向边。我们将tarjan算法的极大连通图看成一个点,那么这个过程实际上跟递归求拓扑序是一样的,所以得出一个结论就是我们在算tarjan算法的时候就相当于已经做了一遍拓扑排序,所以不需要在做一遍(虽然求拓扑时间复杂度是线性的),只需要倒序就是拓扑序,分析和上边是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值