Tarjan算法

来源:互联网 发布:筑业家装软件 编辑:程序博客网 时间:2024/06/14 19:53

http://blog.sina.com.cn/s/blog_69a101130100k1cm.html#cmt_3184785




#include <iostream>#include <string.h>#include <vector>#include <algorithm>#include <stack>#include <stdio.h>using namespace std;#define  LL long longconst int maxn = 10000+6;vector<int>G[maxn];vector<int>len;int DFN[maxn],low[maxn],instack[maxn];stack<int> q;int tm=0;int n,m;void add(int u,int v){    len.push_back(v);    G[u].push_back((int)len.size()-1);}void tarjan(int now){    DFN[now]=low[now]=++tm;    q.push(now);    instack[now]=1;    for(int i=0;i<G[now].size();i++)    {        int to=len[G[now][i]];        if(DFN[to]==0)        {            tarjan(to);            if(low[now]>low[to]) low[now]=low[to];        }        else if(instack[to]==1&&low[now]>DFN[to])            low[now]=DFN[to];//这里是一直让我很疑惑的,为什么不low[now]和low[to]比较,而是DFN[to]    }    if(DFN[now]==low[now])    {        int v;        do        {            //遍历这个强连通分量,可以输出或者干嘛干嘛            v=q.top();            instack[v]=0;            q.pop();                    }while(now!=v);    }    }void init(){    for(int i=0;i<maxn;i++)    {        G[i].clear();    }    while(!q.empty()) q.pop();    len.clear();    memset(DFN,0,sizeof DFN);    memset(low,0,sizeof low);    memset(instack,0,sizeof instack);}int main(){    while(~scanf("%d %d",&n,&m))    {        if(n==m&&n==0) break;        init();        for(int i=1;i<=m;i++)        {            int u,v;            scanf("%d %d",&u,&v);            add(u,v);        }        for(int i=1;i<=n;i++)            if(DFN[i]==0)                tarjan(i);    }}




原创粉丝点击