码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2762 tarjan缩点+拓扑

时间:2014-10-06 19:01:31      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   io   os   ar   for   strong   

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

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


题目意思:
给出一个结点数目为n,边数为m的有向图,若随意选出两个结点x、y,若能从x到y或者(注意,不是而且)y到x,输出Yes,否则输出No。

思路:
在强连通里肯定成立,若不成立,肯定在两个强连通分量里面,那么狠容易想到缩点分块了。画了几个图后发现若分块后的图为单链那么肯定成立,若不是单链即有分叉的话那么不成立,自然而然想到拓扑了,每次删除一个入度为0的点,就看一下入度为0的点为多少个,若>1则不成立。

代码:
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <vector>
  6 #include <queue>
  7 #include <stack>
  8 using namespace std;
  9 
 10 #define N 10005
 11 
 12 int low[N], dfn[N], dfn_clock;
 13 int instack[N], a[N], in[N];
 14 int n, m;
 15 stack<int>st;
 16 vector<int>ve[N],out[N];
 17 int ans, num;
 18 
 19 void init(){
 20     int i;
 21     for(i=0;i<=n;i++){
 22         ve[i].clear();instack[i]=1;
 23         out[i].clear();
 24     }
 25     memset(dfn,0,sizeof(dfn));
 26     memset(in,0,sizeof(in));
 27 }
 28 
 29 void tarjan(int u){
 30     int v, i, j;
 31     dfn[u]=low[u]=dfn_clock++;
 32     st.push(u);
 33     for(i=0;i<ve[u].size();i++){
 34         v=ve[u][i];
 35         if(!dfn[v]){
 36             tarjan(v);
 37             low[u]=min(low[u],low[v]);
 38         }
 39         else if(instack[v]){
 40             low[u]=min(low[u],dfn[v]);
 41         }
 42     }
 43     if(low[u]==dfn[u]){
 44         ans++;
 45         while(1){
 46             v=st.top();st.pop();
 47             instack[v]=0;
 48             a[v]=ans;
 49             if(v==u){
 50                 break;
 51             }
 52         }
 53     }
 54 }
 55 
 56 main()
 57 {
 58     int i, j, k;
 59     int x, y;
 60     int t;
 61     cin>>t;
 62     
 63     while(t--){
 64         scanf("%d %d",&n,&m);
 65         init();
 66         while(m--){
 67             scanf("%d %d",&x,&y);
 68             ve[x].push_back(y);
 69         }
 70         dfn_clock=1;ans=0;
 71         for(i=1;i<=n;i++){
 72             if(!dfn[i])
 73             tarjan(i);
 74         }
 75         for(i=1;i<=n;i++){
 76             for(j=0;j<ve[i].size();j++){
 77                 x=ve[i][j];
 78                 if(a[x]!=a[i]){
 79                     in[a[x]]++;
 80                     out[a[i]].push_back(a[x]);
 81                 }
 82             }
 83         }
 84         int aa, f;
 85     //    printf("%d\n",ans);
 86 //        for(i=1;i<=n;i++){
 87     //        printf("%d ",a[i]);
 88     //    }
 89     //    cout<<endl;
 90         for(i=1;i<=ans;i++){
 91             aa=0;f=0;
 92             for(j=1;j<=ans;j++){
 93                 if(!in[j]) aa++;
 94                 if(!in[j]&&!f){
 95                     for(k=0;k<out[j].size();k++){
 96                         in[out[j][k]]--;
 97                     }
 98                     in[j]=-1;f=1;
 99                 } 
100                 
101             }
102             
103             if(aa>1) break;
104             
105         }
106         if(aa<=1) printf("Yes\n");
107         else printf("No\n");
108     }
109 }

 

POJ 2762 tarjan缩点+拓扑

标签:des   style   blog   color   io   os   ar   for   strong   

原文地址:http://www.cnblogs.com/qq1012662902/p/4008456.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!