HDU 1269 迷宫城堡(tarjan强联通分量)

来源:互联网 发布:yy软件怎么上马甲 编辑:程序博客网 时间:2024/05/16 15:55

思路:

tarjan求强联通分量个数

代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <string.h>using namespace std;int ans;//代表着强联通分量的个数//链式前向星const int maxn = 10010;//最大的点的个数int head[maxn];struct edge{    int to,v,next;}edg[100100];int cnte;void addedge(int x,int y,int v){    edg[++cnte].to = y;    edg[cnte].v = v;    edg[cnte].next = head[x];    head[x] = cnte;}int dfn[maxn];int low[maxn];int stak[maxn];int visstak[maxn];int cntstak = 0;int belong[maxn];int index;void tarjan(int u){    dfn[u] = low[u] = ++index;    stak[cntstak++] = u;    visstak[u] = 1;    for(int i = head[u];i != -1;){        int v = edg[i].to;        if(!dfn[v]){            tarjan(v);            low[u] = min(low[u],low[v]);        }        else if(visstak[v]){            low[u] = min(low[u],dfn[v]);        }//第三种情况则是已经找完的点,对于这些点我们不再访问        i = edg[i].next;    }    if(dfn[u] == low[u]){        ans++;        int v;        do{            v = stak[--cntstak];            visstak[v] = 0;            belong[v] = ans;        }while(v != u);    }}void ini(){    ans = 0;    cnte = 0;    index = 0;    cntstak = 0;    memset(head,-1,sizeof(head));    memset(low,0,sizeof(low));    memset(dfn,0,sizeof(dfn));}int main(){    int n,m;    while(~scanf("%d%d",&n,&m),n||m){        ini();        int a,b;        for(int i = 1;i <= m;i++){            scanf("%d%d",&a,&b);            addedge(a,b,1);        }        for(int i = 1;i <= n;i++){            if(dfn[i] == 0){                tarjan(i);            }        }        if(ans == 1){            printf("Yes\n");        }        else{            puts("No");        }    }    return 0;}
0 0