tarjan

Posted tushukai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tarjan相关的知识,希望对你有一定的参考价值。

TARJAN算法

我先介绍一下这个算法是来干啥的:
它的用处是求强连通分量。 那么,强连通分量又是啥??

在一个有向图中,
强连通:如果两个顶点可以相互通达,则称两个顶点 强连通(strongly connected)
如果有向图G的每两个顶点都 强连通,称G是一个强连通图。非 强连通图有向图的极大强连通 子图,称为强连通分量(strongly connected components)。

算法思路:

第一点,对象图不一定是一个连通图。所以,为了判断每个点是否连通,我们引入一个时间戳。如果他==0则深搜搜他!!

我们还要定义一个变量:low[ ]:该子树中,且仍在栈中的最小时间戳,像是确立了一个关系,low[ ]相等的点在同一强连通分量中。

然后对于搜到的点寻找与其有边相连的点,判断这些点是否已经被搜索过,若没有,则进行搜索。若该点已经入栈,说明形成了环,.则更新low

在不断深搜的过程中如果没有路可走了(出边遍历完了),那么就进行回溯,回溯时不断比较low[ ],去最小的low值。如果dfn[x]==low[x]则x可以看作是某一强连通分量子树的根,也说明找到了一个强连通分量,然后对栈进行弹出操作,直到x被弹出。

算法模板:

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1005;
int x,y,n,id,t,flag,test;
int dfn[N],head[N],block[N],low[N];
struct Node
    int v,next;
e[N*N];
int max(int A,int B) return A>B? A:B; 
int min(int A,int B) return A>B? B:A;
void add(int u,int v) e[id].v=v;e[id].next=head[u];head[u]=id++;
#define to e[i].v
void tj(int u)

    dfn[u]=low[u]=++t;
    for (int i=head[u];i;i=e[i].next)
    if (!dfn[to]) 
    
        tj(to);
        low[u]=min(low[u],low[to]);
        if (low[to]>=dfn[u]) ++block[u];
    
    else low[u]=min(low[u],dfn[to]);

 
int main()
    while(1)
        scanf("%d",&x);
        if (x==0) break;
        memset(e,0,sizeof(e));
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(head,0,sizeof(head));
        id=1;t=flag=n=0;
        scanf("%d",&y);add(x,y);add(y,x);n=max(n,x);n=max(n,y);
        whille(1)
            int u,v;
            scanf("%d",&u);
            if (u==0) break;
            scanf("%d",&v);
            add(u,v);add(v,u);
            n=max(n,u);n=max(n,v);
        
        for (int i=1;i<=n;i++) block[i]=1;block[1]=0;
        tj(1);
        printf("Network #%d\n",++test);
        for(int i=1;i<=n;i++)
           if(block[i]>1)
                       printf("  SPF node %d leaves %d subnets\n",i,block[i]);
                       flag=1;
              
           if(!flag)printf("  No SPF nodes\n");
        printf("\n");   
    
    return 0;

感谢https://blog.csdn.net/yklcy_1334/article/details/54563832!!!

以上是关于tarjan的主要内容,如果未能解决你的问题,请参考以下文章

tarjan算法与拓扑排序

Tarjan&&缩点简析

小白入门向tarjan算法+codevs1332题解报告