链接:http://poj.org/problem?id=2186
题意:给你N个点,然后在给你N条有向边,然后让你找出这样的点S,S满足条件图上任意一点都能到达S。
要想满足任意一点都能到达,首先满足图连通,然后满足将图缩点后形成一个棵树,树的特征是可以有且只有一个点的出度为0。
然后代码如下:
1 #include <iostream> 2 #include <vector> 3 #include <queue> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <stack> 8 9 using namespace std; 10 const int maxn = 50050; 11 12 struct edge 13 { 14 int u,v,val; 15 }; 16 int dfn[10050],low[10050],belong[10050],inst[10050]; 17 vector<edge> edges; 18 vector<int>g[maxn]; 19 stack<int>st; 20 int bcnt,cnt,time; 21 22 void init(int n) 23 { 24 int i; 25 for(i =0;i <= n;i++) 26 g[i].clear(); 27 28 edges.clear(); 29 time = 0;bcnt = cnt = 0; 30 return ; 31 } 32 void addedge(int u,int v,int val) 33 { 34 edges.push_back((edge){u,v,1}); 35 g[u].push_back(cnt); 36 cnt++; 37 38 return ; 39 } 40 void tarjan(int i) 41 { 42 int j; 43 dfn[i] = low[i] = ++time; 44 inst[i] = 1; 45 st.push(i); 46 47 for(j = 0;j < g[i].size();j++) 48 { 49 edge e; 50 e = edges[g[i][j]]; 51 int v; 52 v = e.v; 53 if(!dfn[v]) 54 { 55 tarjan(v); 56 low[i] = min(low[i],low[v]); 57 } 58 else if(inst[v] && dfn[v] < low[i]) 59 low[i] = dfn[v]; 60 } 61 if(dfn[i] == low[i]) 62 { 63 //cout<<i<<"****"<<endl; 64 bcnt++; 65 do 66 { 67 j = st.top(); 68 st.pop(); 69 inst[j] = 0; 70 belong[j] = bcnt; 71 //printf("%d *",j); 72 } 73 while(j != i); 74 //puts(""); 75 } 76 77 } 78 void tarjans(int n) 79 { 80 int i; 81 bcnt = time = 0; 82 while(!st.empty())st.pop(); 83 memset(dfn,0,sizeof(dfn)); 84 85 memset(inst,0,sizeof(inst)); 86 memset(belong,0,sizeof(belong)); 87 for(i = 1;i <= n;i++) 88 if(!dfn[i])tarjan(i); 89 } 90 int main() 91 { 92 int n,m; 93 //freopen("in.txt","r",stdin); 94 while(~scanf("%d %d",&n,&m)) 95 { 96 int a,b,i; 97 init(n); 98 for(i = 0;i < m;i++) 99 { 100 scanf("%d %d",&a,&b); 101 addedge(a,b,1); 102 103 104 } 105 tarjans(n); 106 //cout<<bcnt<<endl; 107 int leap = 0,flag = 0; 108 int bcnt0,j; 109 int outbc[10050]; 110 memset(outbc,0,sizeof(outbc)); 111 for(i = 1;i <= n;i++) 112 { 113 for(j = 0;j < g[i].size();j++) 114 { 115 int v; 116 v = edges[g[i][j]].v; 117 if(belong[i] != belong[v]){ 118 if(outbc[belong[i]] == 0) 119 leap++; 120 outbc[belong[i]] = 1; 121 } 122 } 123 } 124 if(leap == bcnt-1) 125 { 126 int ans; 127 ans = 0; 128 for(i = 1;i < bcnt+1;i++) 129 { 130 if(outbc[i] == 0) 131 break; 132 } 133 for(j = 1;j <= n;j++) 134 if(belong[j] == i) 135 ans++; 136 137 printf("%d ",ans); 138 } 139 else 140 puts("0"); 141 142 143 } 144 return 0; 145 }