[poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud
 
 
Going from u to v or from v to u?
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 14778   Accepted: 3911

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

题意:给一个图,问是否为单向连通。

Kosaraju+缩点,然后拓扑序搞一下,若只有一条没有分支的链,则Yes,否则No

  1 #include <iostream>

  2 #include <cstring>

  3 #include <cstdio>

  4 #include <vector>

  5 using namespace std;

  6 const int maxn=1010;

  7 vector<int>G[maxn];

  8 vector<int>rG[maxn];

  9 vector<int>vs;

 10 int vis[maxn];

 11 int cmp[maxn];

 12 int last[maxn];

 13 int deg[maxn];

 14 int next[maxn];

 15 int V;

 16 vector<int>vc[maxn];

 17 void add_edge(int u,int v)

 18 {

 19     G[u].push_back(v);

 20     rG[v].push_back(u);

 21 }

 22 void init(int n)

 23 {

 24     for(int i=0;i<n;i++)

 25     {

 26         G[i].clear();

 27         rG[i].clear();

 28         vc[i].clear();

 29         vis[i]=0;

 30         last[i]=-1;

 31         deg[i]=0;

 32         next[i]=-1;

 33     }

 34 }

 35 void dfs(int v)

 36 {

 37     vis[v]=1;

 38     for(int i=0;i<G[v].size();i++)

 39     {

 40         if(!vis[G[v][i]])dfs(G[v][i]);

 41     }

 42     vs.push_back(v);

 43 }

 44 void rdfs(int v,int k)

 45 {

 46     vis[v]=1;

 47     cmp[v]=k;

 48     vc[k].push_back(v);

 49     for(int i=0;i<rG[v].size();i++)

 50     {

 51         if(!vis[rG[v][i]])rdfs(rG[v][i],k);

 52     }

 53 }

 54 int scc()

 55 {

 56     memset(vis,0,sizeof(vis));

 57     vs.clear();

 58     for(int i=0;i<V;i++)

 59     {

 60         if(!vis[i])dfs(i);

 61     }

 62     memset(vis,0,sizeof(vis));

 63     int k=0;

 64     for(int i=vs.size()-1;i>=0;i--)

 65     {

 66         if(!vis[vs[i]])rdfs(vs[i],k++);

 67     }

 68     return k;

 69 }

 70 int main()

 71 {

 72     ios::sync_with_stdio(false);

 73     int t;

 74     cin>>t;

 75     while(t--)

 76     {

 77         int n,m;

 78         cin>>n>>m;

 79         V=n;

 80         init(n);

 81         int u,v;

 82         for(int i=0;i<m;i++)

 83         {

 84             cin>>u>>v;

 85             add_edge(--u,--v);

 86         }

 87         int k=scc();

 88         memset(vis,0,sizeof(vis));

 89         int flag=1;

 90         int num=0;

 91         for(int i=0;i<k;i++)

 92         {

 93             for(int j=0;j<vc[i].size();j++)

 94             {

 95                 u=vc[i][j];

 96                 for(int l=0;l<G[u].size();l++)

 97                 {

 98                     v=G[u][l];

 99                     if(cmp[u]!=cmp[v])

100                     {

101                         if(last[cmp[v]]==-1)

102                         {

103                             last[cmp[v]]=cmp[u];

104                         }

105                         else if(last[cmp[v]]==cmp[u])continue;

106                         else flag=0;

107                         if(next[cmp[u]]==-1)

108                         {

109                             next[cmp[u]]=cmp[v];

110                         }

111                         else if(next[cmp[u]]==cmp[v])

112                         {

113                             continue;

114                         }

115                         else flag=0;

116                     }

117                 }

118             }

119         }

120         for(int i=0;i<k;i++)

121         {

122             if(last[i]==-1)num++;

123         }

124         if(flag&&num==1)cout<<"Yes"<<endl;

125         else cout<<"No"<<endl;

126     }

127 

128     return 0;

129 }
代码君

 

你可能感兴趣的:(poj)