Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 7699 | Accepted: 3161 |
Description
Input
Output
Sample Input
3 3 1 3 2 3 3 1 2 1 1 2 0
Sample Output
1 3 2
Source
题目大意:给定一个有向图,求一个点集,要求这个点集里的所有点能到达的点,也都能到达这个点。
题目分析:就是求强连通嘛,不过并不是求所有的强连通。因为强连通之间也可能有边相连。将强连通缩点后就将一张有向图转化成DAG,只能将其中出度为0的强连通分量输出,因为只有这些强连通分量中的点能够相互到达。其他的强连通分量可以到达这个强连通分量,但是回不去了,所以不符合。
详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 5005; const int M = 1000005; struct edge { int to,next; }g[M]; int head[N]; int scc[N]; int stack1[N]; int stack2[N]; int out[N]; int vis[N]; int ans[N]; int n,m; void init() { for(int i = 1;i <= n;i ++) { head[i] = -1; scc[i] = out[i] = vis[i] = 0; } } void dfs(int cur,int &sig,int &ret) { vis[cur] = ++ sig; stack1[++stack1[0]] = cur; stack2[++stack2[0]] = cur; for(int i = head[cur];i != -1;i = g[i].next) { if(vis[g[i].to] == 0) dfs(g[i].to,sig,ret); else if(scc[g[i].to] == 0) { while(vis[stack2[stack2[0]]] > vis[g[i].to]) stack2[0] --; } } if(stack2[stack2[0]] == cur) { ++ret; stack2[0] --; do { scc[stack1[stack1[0]]] = ret; }while(stack1[stack1[0] --] != cur); } } int Gabow() { int i,sig,ret; stack1[0] = stack2[0] = sig = ret = 0; for(i = 1;i <= n;i ++) if(!vis[i]) dfs(i,sig,ret); return ret; } void solve() { int i,j,num; num = Gabow(); if(num == 1) { for(i = 1;i < n;i ++) printf("%d ",i); printf("%d\n",i); return; } for(i = 1;i <= n;i ++) { for(j = head[i];j != -1;j = g[j].next) { if(scc[i] != scc[g[j].to]) out[scc[i]] ++; } } int ansnum = 0; for(i = 1;i <= num;i ++) { if(out[i] == 0) { for(j = 1;j <= n;j ++) if(scc[j] == i) ans[ansnum ++] = j; } } sort(ans,ans + ansnum); for(i = 0;i < ansnum - 1;i ++) printf("%d ",ans[i]); printf("%d\n",ans[i]); } int nextint() { char c; int ret; while((c = getchar()) > '9' || c < '0') ; ret = c - '0'; while((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + c - '0'; return ret; } int main() { int i,j,a,b; while(n = nextint(),n) { m = nextint(); init(); for(i = 1;i <= m;i ++) { a = nextint(); b = nextint(); g[i].to = b; g[i].next = head[a]; head[a] = i; } solve(); } return 0; } //996K 110MS