标签:
题意:定义了一个图的底(bottom),是指在一个图中能够被所有点到达的点,问途中有哪些点是图的底。
首先是同一个强连通分量中的点都能够互相到达,强连通分量中一个点能到达其他点,也必然代表该强连通分量中的点能到达那个点,所以首先强连通,然后此时如果一个点是有出度的,那么它指向的点必然不能到它,所以其实就是求出度为 0 的强连通分量内的点。
1 #include<stdio.h>
2 #include<string.h>
3 #include<stack>
4 #include<queue>
5 using namespace std;
6
7 const int maxn=5e3+5;
8 const int maxm=1e5+5;
9
10 int head[maxn],point[maxm],nxt[maxm],size;
11 int n,t,scccnt;
12 int stx[maxn],low[maxn],scc[maxn];
13 int od[maxn];
14 stack<int>S;
15
16 void init(){
17 memset(head,-1,sizeof(head));
18 size=0;
19 memset(od,0,sizeof(od));
20 }
21
22 void add(int a,int b){
23 point[size]=b;
24 nxt[size]=head[a];
25 head[a]=size++;
26 }
27
28 void dfs(int s){
29 stx[s]=low[s]=++t;
30 S.push(s);
31 for(int i=head[s];~i;i=nxt[i]){
32 int j=point[i];
33 if(!stx[j]){
34 dfs(j);
35 low[s]=min(low[s],low[j]);
36 }
37 else if(!scc[j]){
38 low[s]=min(low[s],stx[j]);
39 }
40 }
41 if(low[s]==stx[s]){
42 scccnt++;
43 while(1){
44 int u=S.top();S.pop();
45 scc[u]=scccnt;
46 if(s==u)break;
47 }
48 }
49 }
50
51 void setscc(){
52 memset(stx,0,sizeof(stx));
53 memset(scc,0,sizeof(scc));
54 t=scccnt=0;
55 for(int i=1;i<=n;++i)if(!stx[i])dfs(i);
56 for(int i=1;i<=n;++i){
57 for(int j=head[i];~j;j=nxt[j]){
58 int k=point[j];
59 if(scc[i]!=scc[k]){
60 od[scc[i]]++;
61 }
62 }
63 }
64 }
65
66 int main(){
67 int m;
68 while(scanf("%d",&n)!=EOF&&n){
69 scanf("%d",&m);
70 init();
71 while(m--){
72 int a,b;
73 scanf("%d%d",&a,&b);
74 add(a,b);
75 }
76 setscc();
77 int cnt=0;
78 for(int i=1;i<=n;++i)if(!od[scc[i]]){
79 if(cnt++)printf(" ");
80 printf("%d",i);
81 }
82 printf("\n");
83 }
84 return 0;
85 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4814880.html