tarjan算法求有向图的强连通分量

tarjan算法求有向图的强连通分量

有向图的强连通分量

  1. 什么是强连通?

强连通:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,即两点可以相互到达,则称两个顶点强连通。

  1. 什么是连通分量?

联通分量:有向图中任意两个不同顶点都可以相互到达(即任意两顶点都是强连通的)的子图称为一个连通分量。

  1. 什么是有向图的强连通分量?

有向图强连通分量:有向图的极大强连通分量,称为强连通分量。

  1. 强连通分量有什么用处?

可以通过将所有连通分量缩成一个点把任意一个有向图转化成一张有向无环图

tarjan算法

Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度。

算法流程

Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。
定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号。
当DFN(u)=Low(u)时,以u为根的搜索子树上所有节点是一个强连通分量。

算法模板

const int N = xxxx;
int  n;
int h[N], e[M], ne[M], idx;  //存图
int dfn[N], low[N], timeid;  //时间戳
int stk[N], top; //模拟栈
int id[N], len[N], cnt;  //每个节点所在连通分量标号, 每个连通分量内顶点数量, 连通分量数量
int dout[N], din[N]; //初度入度
bool st[N];

void tarjan(int u){
    dfn[u] = low[u] = ++timeid;
    stk[++top]=u;
    st[u]=true;
    for(int i=h[u]; i; i=ne[i]){
        int j=e[i];
        if(!dfn[j]){
            tarjan(j);
            low[u]=min(low[u], low[j]);
        }
        else if(st[j])
            low[u]=min(low[u], dfn[j]);
    }
    if(dfn[u]==low[u]){
        ++cnt;
        int y;
        do{
            y=stk[top--];
            st[y]=false;
            id[y]=cnt;
            len[cnt]++;
        }while(y!=u);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值