zoukankan      html  css  js  c++  java
  • 求强联通分量——Tarjan算法

    const int MAXN=5010;
    const int MAXM=2500000;
    
    struct Edge
    {
        int to,next;
    }edge[MAXM];
    
    int head[MAXN],tot;
    int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];
    int Index,top;
    int scc;
    bool Instack[MAXN];
    int num[MAXN];
    
    void addedge(int u,int v)
    {
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    
    void Tarjan(int u)
    {
        int v;
        Low[u]=DFN[u]=++Index;
        Stack[top++]=u;
        Instack[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].to;
            if(!DFN[v])
            {
                Tarjan(v);
                if(Low[u]>Low[v])
                    Low[u]=Low[v];
            }
            else if(Instack[v]&&Low[u]>DFN[v])
                Low[u]=DFN[v];
        }
        if(Low[u]==DFN[u])
        {
            scc++;
            do
            {
                v=Stack[--top];
                Instack[v]=false;
                Belong[v]=scc;
                num[scc]++;
            }
            while(u!=v);
        }
    }
    
    void solve(int N)//N代表点的个数,点的标号从1到N,最后得到的结果在Belong数组中,记录的是改点属于的强联通分量的标号,scc代表强联通分量的个数
    {
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof(Instack));
        memset(num,0,sizeof(num));
        Index=scc=top=0;
        for(int i=1;i<=N;i++)
        {
            if(!DFN[i])
                Tarjan(i);
        }
    }
    
    void init()
    {
        tot=0;
        memset(head,-1,sizeof(head));
    }
  • 相关阅读:
    Add Two Numbers
    Reverse Linked List II
    Reverse Linked List
    Remove Duplicates from Sorted List
    Remove Duplicates from Sorted List II
    Partition List
    Intersection of Two Linked Lists
    4Sum
    3Sum
    2Sum
  • 原文地址:https://www.cnblogs.com/wsruning/p/5749195.html
Copyright © 2011-2022 走看看