poj 2553 The Bottom of a Graph (Tarjan強聯通)
阿新 • • 發佈:2018-11-01
題意:在v可以到達的所有點也都可以到達v,由此就可以知道求解縮點以後出度為0的點中的節點數字即可
思路:就是縮點後,輸出出度為0的點內的點。
#pragma GCC optimize(2) #include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<set> #include<vector> #include<string> #include<queue> using namespace std; const int maxn = 5005; const int inf = 0x3f3f3f3f; typedef long long ll; int head[maxn], belong[maxn], Stack[maxn], instack[maxn], low[maxn], dfn[maxn]; int ou[maxn]; int n, m, tot, cnt; int sum, top; struct node { int u, v, next; }edge[maxn*maxn]; void addedge(int u, int v) { edge[tot].u = u; edge[tot].v = v; edge[tot].next = head[u]; head[u] = tot++; return; } void init() { tot = cnt = 0; top = 0; sum = 0; memset(head, -1, sizeof(head)); memset(dfn, 0, sizeof(dfn)); memset(Stack, 0, sizeof(Stack)); memset(instack, 0, sizeof(instack)); memset(low, 0, sizeof(low)); memset(belong, 0, sizeof(belong)); memset(ou, 0, sizeof(ou)); return; } void tarjan(int u) { dfn[u] = low[u] = ++cnt; Stack[top++] = u; instack[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if (instack[v]) { low[u] = min(low[u], dfn[v]); } } if (low[u] == dfn[u]) { int v; sum++; do { v = Stack[--top]; instack[v] = 0; belong[v] = sum; } while (u!=v); } } int main() { //freopen("C://input.txt", "r", stdin); while (scanf("%d%d", &n,&m)&&n!=0) { init(); for (int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); addedge(u, v); } for (int i = 1; i <= n; i++) { if (!dfn[i]) { tarjan(i); } } for (int i = 1; i <= n; i++) { for (int j = head[i]; j != -1; j = edge[j].next) { int v = edge[j].v; if (belong[i] != belong[v]) { ou[belong[i]]++; } } } for (int i = 1; i <= n; i++) { if (!ou[belong[i]] ) { printf("%d ", i); } } printf("\n"); } return 0; }