【图论补完计划】poj 2762 (强连通分量 kosaraju)

Going from u to v or from v to u?
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 17479   Accepted: 4694

Description

In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?

Input

The first line contains a single integer T, the number of test cases. And followed T cases.

The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.

Output

The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.

Sample Input

1
3 3
1 2
2 3
3 1

Sample Output

Yes


题意
询问一个有向图的任意两点s,t,是否存在s可达t或t可达s,如果都存在输出Yes,否则输出No。

做法

scc拆点,建图,记录入度,如果存在两个及两个以上的入度为0的点则无解,找到入度为0的点作为根进行dfs,因为是一条链,如果出现分叉点(新图的点的邻接边数目>=2)则无解。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 const int maxn=1005;
 10 
 11 vector<int> G[maxn];
 12 vector<int> rG[maxn];
 13 vector<int> nG[maxn];
 14 vector<int> vs;
 15 
 16 int n,m;
 17 
 18 int cmp[maxn],d[maxn];
 19 bool used[maxn],tag;
 20 
 21 inline int read(){
 22     int x=0,f=1;char ch=getchar();
 23     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
 24     while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
 25     return x*f;
 26 }
 27 
 28 void init(){
 29     for(int i=0;i<maxn;i++){
 30         G[i].clear();rG[i].clear();nG[i].clear();
 31         d[i]=0;cmp[i]=0;
 32     }
 33     tag=false;
 34 }
 35 
 36 void add_edge(int s,int t){
 37     G[s].push_back(t);
 38     rG[t].push_back(s);
 39 }
 40 
 41 void dfs(int s){
 42     used[s]=true;
 43     for(int i=0;i<G[s].size();i++){
 44         if(!used[G[s][i]]) dfs(G[s][i]);
 45     }
 46     vs.push_back(s);
 47 }
 48 
 49 void rdfs(int s,int k){
 50     used[s]=true;
 51     cmp[s]=k;
 52     for(int i=0;i<rG[s].size();i++){
 53         if(!used[rG[s][i]]) rdfs(rG[s][i],k);
 54     }
 55 }
 56 
 57 void ndfs(int root){
 58     if(nG[root].size()>1){
 59         tag=true;
 60         return;
 61     }
 62     if(nG[root].size()==0) return;
 63     ndfs(nG[root][0]);
 64 }
 65 
 66 int scc(){
 67     memset(used,0,sizeof(used));
 68     vs.clear();
 69     for(int i=1;i<=n;i++){
 70         if(!used[i]) dfs(i);
 71     }
 72     memset(used,0,sizeof(used));
 73     int k=0;
 74     for(int i=vs.size()-1;i>=0;i--){
 75         if(!used[vs[i]]) rdfs(vs[i],++k);
 76     }
 77     return k;
 78 }
 79 
 80 int main(){
 81     int T;
 82     T=read();
 83     while(T--){
 84         init();
 85         n=read();m=read();
 86         for(int i=0;i<m;i++){
 87             int s,t;
 88             s=read();t=read();
 89             add_edge(s,t);
 90         }
 91         int k=scc();
 92         for(int i=1;i<=n;i++){
 93             for(int j=0;j<G[i].size();j++){
 94                 int v=G[i][j];
 95                 if(cmp[i]==cmp[v]) continue;
 96                 nG[cmp[i]].push_back(cmp[v]);
 97                 d[cmp[v]]++;
 98             }
 99         }
100         int root=0;bool flag=false;
101         for(int i=1;i<=k;i++){
102             if(d[i]==0){
103                 if(root){
104                     flag=true;
105                     break;
106                 }
107                 root=i;
108             }
109         }
110         if(flag){
111             printf("No\n");
112         }
113         else{
114             ndfs(root);
115             if(!tag) printf("Yes\n");
116             else printf("No\n");
117         }
118     }
119     return 0;
120 }

 

 
posted @ 2017-03-09 20:32  hymscoty  阅读(209)  评论(0编辑  收藏  举报