Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 8902 | Accepted: 3688 |
Description
Input
Output
Sample Input
3 3 1 3 2 3 3 1 2 1 1 2 0
Sample Output
1 3 2
Source
#include<map> #include<set> #include<list> #include<stack> #include<queue> #include<vector> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 100010; const int M = 200010; const int inf = 0x3f3f3f3f; int DFN[N]; int low[N]; int block[N]; int Stack[N]; int out[N]; bool instack[N]; int head[N]; int ans[N]; int tot, sccnum, index, top, n, m; struct node { int next; int to; }edge[M]; void addedge(int from, int to) { edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } void init() { memset( instack, 0, sizeof(instack) ); memset( DFN, 0, sizeof(DFN) ); memset( low, 0, sizeof(low) ); memset( out, 0, sizeof(out) ); sccnum = index = top = 0; } void tarjan(int u) { DFN[u] = low[u] = ++index; Stack[top++] = u; instack[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (DFN[v] == 0) { tarjan(v); if (low[u] > low[v]) { low[u] = low[v]; } } else if (instack[v]) { if (low[u] > DFN[v]) { low[u] = DFN[v]; } } } if (DFN[u] == low[u]) { sccnum++; do { top--; block[Stack[top]] = sccnum; instack[Stack[top]] = 0; }while (Stack[top] != u); } } void solve() { init(); for (int i = 1; i <= n; i++) { if (DFN[i] == 0) { tarjan(i); } } for (int i = 1; i <= n; i++) { for (int j = head[i]; j != -1; j = edge[j].next) { if (block[i] != block[edge[j].to]) { out[block[i]]++; } } } int cnt = 0; for (int i = 1; i <= n; i++) { if (out[block[i]] == 0) { ans[cnt++] = i; } } sort(ans, ans + cnt); printf("%d", ans[0]); for (int i = 1; i < cnt; i++) { printf(" %d", ans[i]); } printf("\n"); } int main() { while (~scanf("%d", &n), n) { scanf("%d", &m); memset( head, -1, sizeof(head) ); tot = 0; int u, v; for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); addedge(u, v); } solve(); } return 0; }