题目链接: 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 }