码迷,mamicode.com
首页 > 编程语言 > 详细

tarjan算法

时间:2018-05-16 00:45:55      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:bre   code   ast   last   []   min   ext   FN   算法   

定义

dfn[x]:DFN过程中到x点的时间
low[x]:最小的x能达到的点的dfn
当x进栈时dfn[x]=low[x]
part[x]:x所在的强连通分量

代码解释

//强连通分量
int tarjan(int x)
{
    d[++tot]=x;//进栈
    dfn[x]=low[x]=++dd;//初始化dfn[]以及low[]
    for(int i=last[x];i;i=next[i])
    {
        int j=to[i];
        if(!dfn[j])//当没走过j是,遍历j
        {
            tarjan(j);
            low[x]=min(low[x],low[j]);//因为x可以走到j,所以更新low[]
        }
        else
        if(!part[j])//只有当j还在栈中是才可以更新low。因为当j不在栈中时,j并不能遍历到x
            low[x]=min(low[x],low[j]);
    }
    if(dfn[x]==low[x])//表示x无法回溯到更小的dfn
    {
        num++;//num表示强连通分量个数
        while(dfn[d[tot]]>=dfn[x])//退栈,在栈中比x后进栈的节点都与x属于同一个强连通分量
        {
            part[d[tot--]]=num;
        }
    }
}
//人工栈代码
long long tarjan(long long x1)
{
    z[top=1]=x1;
    while(top)
    {
        long long x=z[top];
        if(!dfn[x])
        {
            dfn[x]=low[x]=++tot;
            d[++dd]=x;
        }
        long long i;
        for(i=last[x];i;i=next[i])
        {
            if(!dfn[to[i]])
            {
                break;
            }
            else
            if(!belong[to[i]])
                low[x]=min(low[to[i]],low[x]);
        }
        if(!i && top>1) 
            low[z[top-1]]=min(low[z[top-1]],low[x]);
        if(!i)
        {
            if(dfn[x]==low[x])
            {
                be++;
                while(dd && low[d[dd]]>=dfn[x])
                {
                    belong[d[dd]]=be;
                    sum[be]+=a[d[dd]];
                    dd--;
                }
            }
            top--;
        }
        else
            z[++top]=to[i];
    }
}
//双连通分量
int tarjan(int x,int fa)
{
    low[x]=dfn[x]=++tot;
    d[++dd]=x;
    for(int i=last[x];i;i=next[i])
    {
        int j=to[i];
        if(i!=fa)//类似于强连通分量,只有保证不走来的边就可以了
        {
            if(!dfn[j])
            {
                tarjan(j,i^1);
                low[x]=min(low[x],low[j]);
            }
            else
                low[x]=min(low[x],dfn[j]);
        }
    }
    if(low[x]==dfn[x])
    {
        num++;
        while(low[d[dd]]>=dfn[x] && dd)
        {
            part[d[dd--]]=num;
            sum[num]++;
        }
    }
}

tarjan算法

标签:bre   code   ast   last   []   min   ext   FN   算法   

原文地址:https://www.cnblogs.com/chen1352/p/9043471.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!