坐井观天

In the name of dream

导航

POJ 2553 Tarjan缩点+判断出度为0

Posted on 2012-04-19 13:47  一毛_  阅读(252)  评论(0编辑  收藏  举报

题目链接: http://poj.org/problem?id=2553

题目大意:

  给定一个n个点的有向图( 1<=n<=5000 ),要求你输出所有满足条件的点,条件是点在 出度为0的强连通分量SCC里,点要按标号大小升序输出。

  (题目我没有看懂,问了lin神后他跟我说的,我一写就ac了。)

分析:

  Tarjan缩点,构图后dfs得到所有SCC的出度值,再遍历所有的点u,如果该点u所属的SCC——belong[u],满足out[ belong[u] ] == 0, 那么加入答案vector,最后输出。

代码:

poj2553
 1 /*2553    Accepted    748K    79MS    C++    2264B    2012-04-19 13:29:35*/
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <vector>
 8 using namespace std;
 9 
10 #define mpair make_pair
11 #define pii pair<int,int>
12 #define MM(a,b) memset(a,b,sizeof(a));
13 typedef long long lld;
14 typedef unsigned long long u64;
15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
17 #define maxn 5010
18 
19 int n,m;
20 vector<int> adj[maxn];
21 
22 int Bcnt, Index, Top;
23 int dfn[maxn], low[maxn];
24 int stack[maxn], belong[maxn];
25 bool vis[maxn];
26 void Tarjan(int u){
27     vis[u]= 1;
28     stack[++Top]= u;
29     dfn[u]= low[u]= ++Index;
30     for(int i=0;i<adj[u].size();++i){
31         int v= adj[u][i];
32         if( !dfn[v] ){
33             Tarjan( v );
34             up_min( low[u], low[v] );
35         }
36         else if( vis[v] )
37             up_min( low[u], dfn[v] );
38     }
39     if( low[u]==dfn[u] ){
40         ++Bcnt;
41         int v;
42         do{
43             v= stack[Top--];
44             vis[v]= 0;
45             belong[v]= Bcnt;
46         }while( u!=v );
47     }
48 }
49 
50 int out[maxn];
51 void dfs(int u){
52     vis[u]=1;
53     for(int i=0;i<adj[u].size();++i){
54         int v= adj[u][i];
55         if( belong[u] != belong[v] )
56             out[ belong[u] ]++;
57         if( !vis[v] )
58             dfs( v );
59     }
60 }
61 
62 vector<int> ans;
63 int main()
64 {
65     while( cin>>n, n ){
66         cin>>m;
67         for(int i=1;i<=n;++i) adj[i].clear();
68         for(int i=1;i<=m;++i){
69             int u,v;
70             scanf("%d%d", &u, &v);
71             adj[u].push_back( v );
72         }
73         Bcnt= Index= Top= 0;
74         for(int i=1;i<=n;++i) low[i]= dfn[i]= vis[i]= 0;
75         for(int i=1;i<=n;++i){
76             if( !dfn[i] )
77                 Tarjan( i );
78         }
79 
80         fill( out+1, out+1+Bcnt, 0 );
81         fill( vis+1, vis+1+n, 0 );
82         for(int i=1;i<=n;++i){
83             if( !vis[i] )
84                 dfs(i);
85         }
86 
87         ans.clear();
88         for(int i=1;i<=n;++i)
89             if( out[ belong[i] ] == 0 )
90                 ans.push_back( i );
91         for(int i=0;i<ans.size();++i)
92             printf("%d%c", ans[i], i==ans.size()-1 ? '\n' : ' ' );
93     }
94 }