题目地址:http://acm.pku.edu.cn/JudgeOnline/problem?id=2762 

这题实际上是判断是否是弱连通的,所以首先强连通,然后缩点,对缩点形成的图最多只能有一个入度为0的点,

如果有多个入度为0的点,则这两个连通分量肯定是不连通的。

   缩点后形成的图形是一棵树,入度为0的点是这颗树的根,这棵树只能是单链,不能有分叉,如果有分叉,则这些

分叉之间是不可达的,所以就对这棵树进行DFS,如果是单链则是YES。

代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
int n,m;
int f[1010];
int times;
bool flag;
int vBlock[1010];
bool visited[1010];
int in[1010];
vector <int> map1[1010];
vector <int> map2[1010];
vector <int> map3[1010];
int numCnt;
void dfs1(int v)
{
    visited[v] = true;
    
for (int i=0;i<map1[v].size();i++)
    {
        
int cur = map1[v][i];
        
if (!visited[cur])
        {
            dfs1(cur);
        }
    }
    f[times++= v;
}
void dfs2(int v,int id)
{
    vBlock[v] = id;
    visited[v] = true;
    
for (int i=0;i<map2[v].size();i++)
    {
        
int cur = map2[v][i];
        
if (!visited[cur])
        {
            dfs2(cur,id);
        }
    }
}
void dfs(int v)
{
    numCnt++;
    
int len = map3[v].size();
    
if (len>1)
    {
        flag = false;
        
return;
    }
    
else if (len==1)
    {
        dfs(map3[v][0]);
    }
}
int main()
{
    
int T;
    scanf("%d",&T);
    
while (T--)
    {
        memset(visited,false,sizeof(visited));
        times = 0;

        scanf("%d%d",&n,&m);
        
for (int i=1;i<=n;i++)
        {
            map1[i].clear();
            map2[i].clear();
            map3[i].clear();
        }
        
for (int i=1;i<=m;i++)
        {
            
int a,b;
            scanf("%d%d",&a,&b);
            map1[a].push_back(b);
            map2[b].push_back(a);
        }
        
for (int i=1;i<=n;i++)
        {
            
if (!visited[i])
            {
                dfs1(i);
            }
        }
        memset(visited,false,sizeof(visited));
        memset(vBlock,0,sizeof(vBlock));
        
int block = 0;
        
for (int i=times-1;i>=0;i--)
        {
            
if (!visited[f[i]])
            {
                dfs2(f[i],++block);
            }
        }
       
// printf("Block %d\n",block);
        memset(in,0,sizeof(in));
        
for (int i=1;i<=n;i++)
            
for (int j=0;j<map1[i].size();j++)
            {
                
int cur = map1[i][j];
                
if (vBlock[i]!=vBlock[cur])
                {
                    map3[vBlock[i]].push_back(vBlock[cur]);
                    
in[vBlock[cur]]++;
                }
            }
        
int cnt =0;
        
int fst;
        
for (int i=1;i<=block;i++)
        {
            
if (in[i]==0)
            {
                cnt++;
                fst = i;
            }
        }
        
if (cnt>1)
        {
            printf("No\n");
        }
        
else
        {
            flag  = true;
            numCnt = 0;
            dfs(fst);
            
if (flag&&numCnt==block)
            {
                printf("Yes\n");
            }
            
else
            {
                printf("No\n");
            }
        }

    }
    
return 0;
}