题意:判断是否存在从任意一个起点开始都可以走完余下任何一个点。

解题思路:有向联通图,判断联通分量是否为1。

解题补充知识点:在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。有向图中, u可达v不一定意味着v可达u. 相互可达则属于同一个强连通分量。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269

View Code
#include <iostream>
using namespace std;
#include <stack>
#include <vector>
const int MAX=10000+10;
vector<int >map[MAX];//构建邻接表
stack<int >s;//将更新到的店入栈
int Dfs[MAX];//访问的节点次序//u或u的子树能够追溯到的最早的栈中节点的序号(时间戳)
int Low[MAX];//父节点最早出现的时间戳//节点u搜索的序号(时间戳)
bool isStack[MAX];//是否在栈中
int used[MAX];//标记该点输入哪个联通分量
int top;//时间戳
int newflag;//联通分量
void init()//各种初始化
{
    memset(Dfs,0,sizeof(Dfs));
    memset(Low,0,sizeof(Low));
    memset(isStack,false,sizeof(isStack));
    memset(used,0,sizeof(used));
    for(int i=0;i<MAX;i++)
    {
        map[i].clear();
    }
    while(!s.empty())
    {
        s.pop();
    }
    newflag=0;
    top=0;
}
void tarjan(int u)
{
    Dfs[u]=Low[u]=++top;//时间戳
    isStack[u]=true;//存在栈中
    s.push(u);
    for(int x=0;x<map[u].size();x++)
    {
        int v=map[u][x];
        if(!Dfs[v])//判断是否更新过
        {
            tarjan(v);//递归,继续更新
            if(Low[v]<Low[u])//若存在子节点能找到比父节点更早节点,即有环
            {
                Low[u]=Low[v];
            }
        }
        else if(isStack[v]&&Dfs[v]<Low[u])
        {
            Low[u]=Dfs[v];
        }
    }
    if(Dfs[u]==Low[u])//找不到邻接点了,即找到联通分量的结束条件
    {
        newflag++;
        int x;
        do
        {
            x=s.top();
            isStack[x]=false;
            used[x]=newflag;
            s.pop();
        }while(x!=u);//输出联通分量
    }
    return;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m),n+m)
    {
        init();
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            map[x].push_back(y);
        }
        for(i=1;i<=n;i++)
        {
            if(!Dfs[i])
            {
                tarjan(i);
            }
        }
        if(newflag==1)
        {
            printf("Yes\n");
        }
        else printf("No\n");
    }
    return 0;
}