有向图强连通分量Tarjan模板

来源:互联网 发布:sql server数据库开发 编辑:程序博客网 时间:2024/05/23 22:59
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=10010;const int maxm=1000010;int cnt,p[maxn];struct node{    int v,next;}E[maxm];int n,m;int low[maxn],dfn[maxn];int Stack[maxn];///数组模拟栈int num[maxn];///记录第i个连通块点的个数int Scc[maxn];///第i个点属于哪个连通块int scc;///连通块计数int Time;///dfs的时间戳bool instack[maxn];///点是否在栈里int top;///栈里点的个数void init(){    cnt=0;    memset(p,-1,sizeof(p));}void add(int u,int v){    E[cnt].v=v;    E[cnt].next=p[u];    p[u]=cnt++;}void Tarjan(int u){    dfn[u]=low[u]=++Time;    Stack[++top]=u;    instack[u]=1;    int v;    for(int i=p[u];i!=-1;i=E[i].next)    {        v=E[i].v;        if(!dfn[v])///由于dfn初始化为0,所以可以判断是否访问        {            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++;        while(1)        {            v=Stack[top--];            instack[v]=0;            num[scc]++;            Scc[v]=scc;            if(u==v) break;        }    }}void solve(){    for(int i=1;i<=n+1;i++)    {        dfn[i]=num[i]=Scc[i]=0;        instack[i]=0;    }    Time=scc=top=0;    for(int i=1;i<=n;i++)        if(!dfn[i]) Tarjan(i);}int main(){    while(scanf("%d%d",&n,&m),n||m)    {        init();        for(int i=1;i<=m;i++)        {            int x,y;            scanf("%d%d",&x,&y);            add(x,y);        }        solve();        if(scc==1) puts("Yes");        else puts("No");    }    return 0;}

0 0