强连通分量模板

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int maxn=10005;
vector<int> G[maxn];
int N,M,ans; 
bool inq[maxn];  //是否在栈内
int nid,dfn[maxn],low[maxn];  //dfn相当于重新编号,low能搜到的最小编号
stack<int> KK;  //
void init()  //初始化
{
    ans=nid=0;
    for(int i=0;i<=N;i++)
    {
        inq[i]=false;
        dfn[i]=low[i]=0;
    }
    while(!KK.empty()) KK.pop();
}
void Tarjan(int u)
{
    dfn[u]=low[u]=++nid;  //编号
    KK.push(u); inq[u]=true; //丢进栈里
    int Size=G[u].size();
    for(int i=0;i<Size;i++)
    {
        int v=G[u][i];
        if(!dfn[v])  //没有访问过
        {
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(inq[v]) low[u]=min(low[u],dfn[v]); //访问过在栈里
    }
    if(dfn[u]==low[u])//相等说明这是一个连通分量
    {
        ans++;
        int v;
        do
        {
            v=KK.top();  KK.pop();
            inq[v]=false;
        }while(v!=u);
    }
}
int main()
{
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        if(!N&&!M) break;
        for(int i=0;i<=N;i++) G[i].clear();
        int u,v;
        while(M--)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
        }
        init();
        for(int i=1;i<=N;i++) if(!dfn[i]) Tarjan(i);
        if(ans<=1) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
View Code

 

posted @ 2016-07-31 10:14  wust_ouyangli  阅读(110)  评论(0编辑  收藏  举报