HDU1269(Tarjan算法)

//一旦遇到已入栈的点,就将该点作为连通量的根
//这里用dfn[e[i].v]更新的原因是:这个点可能
//已经在另一个强连通分量中了但暂时尚未出栈,所
//以now不一定能到达low[e[i].v]但一定能到达
//dfn[e[i].v].
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e4 + 15;
int n,m;
vector<int> Grape[maxn];
stack<int> s;
bool vis[maxn];
int dfn[maxn],Low[maxn];
int total,ans;
void tarjan(int u)
{
    dfn[u] = Low[u] = ++total;
    s.push(u);//u节点压入栈中
    vis[u] = true;//u节点在栈中
    for(int i=0;i!=Grape[u].size();++i)
    {
        int v = Grape[u][i];
        if(!dfn[v])
        {
            tarjan(v);
            Low[u] = min(Low[u],Low[v]);
        }else if(vis[v]){
            Low[u] = min(Low[u],dfn[v]);
        }
    }
    if(dfn[u]==Low[u])//如果为强连通图的根
    {
        int v;
        do{
            v = s.top();
            s.pop();
            vis[v] = false;//从栈中退出
        }while(v!=u);
        ++ans;
    }
}
int main()
{
    while(cin>>n>>m)
    {
        if(n+m==0)
            break;
        for(int i=1;i<=n;++i)
            Grape[i].clear();
        int u,v;
        for(int i=1;i<=m;++i)
        {
            cin>>u>>v;
            Grape[u].push_back(v);
        }
        memset(dfn,0,sizeof(dfn));
        memset(Low,0,sizeof(Low));
        total = 0;
        ans = 0;
        for(int v=1;v<=n;++v)
        {
            if(!dfn[v])
                tarjan(v);
        }
        if(ans==1)
            cout<<"Yes"<<endl;
        else
            cout<<"No"<<endl;
    }
}

 

posted on 2019-09-23 14:50  chengyulala  阅读(115)  评论(0编辑  收藏  举报

导航