Traversal of P3916 graph in Luogu
Description
- The directed graph of N points and M edges is given. For each point v, find A(v) to represent the point with the largest number that can be reached from point v.
Input
-
Line 1, 2 integers N,M.
Next row M, each row has two integers Ui,Vi, representing the edge (Ui,Vi). Click 1, 2,..., N number.
Output
- N integers A(1),A(2),... A(N)
Sample Input
4 3
1 2
2 4
4 3
Sample Output
4 4 3 4
Explanation:
- When I wrote this question, I didn't see that the opposite side was built, but I saw that the second out was the shrinking point.
- Thinking of practicing hands, I made a reduced point template to cut this problem.
- The idea is to run DAG once after shrinking. Writing better with dfs than topology
#include <iostream> #include <cstdio> #include <cstring> #include <stack> #define N 100005 using namespace std; struct E {int next, to;} e[N]; int n, m, num; int h[N], dp[N], u[N], v[N]; int dex, tot; int low[N], dfn[N], obj[N], bel[N]; bool vis[N]; stack<int> stk; int read() { int x = 0; char c = getchar(); while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();} return x; } void add(int u, int v) { e[++num].next = h[u]; e[num].to = v; h[u] = num; } void tarjan(int x) { low[x] = dfn[x] = ++dex; stk.push(x), vis[x] = 1; for(int i = h[x]; i != 0; i = e[i].next) { int now = e[i].to; if(!dfn[now]) tarjan(now), low[x] = min(low[x], low[now]); else if(vis[now]) low[x] = min(low[x], dfn[now]); } if(low[x] == dfn[x]) { tot++; while(1) { int now = stk.top(); stk.pop(), vis[now] = 0; obj[tot] = max(obj[tot], now); bel[now] = tot; if(now == x) break; } } } void dfs(int x) { if(dp[x]) return; dp[x] = obj[x]; for(int i = h[x]; i != 0; i = e[i].next) { dfs(e[i].to); dp[x] = max(dp[x], dp[e[i].to]); } } int main() { cin >> n >> m; for(int i = 1; i <= m; i++) { u[i] = read(), v[i] = read(); add(u[i], v[i]); } for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); num = 0; memset(h, 0, sizeof(h)); for(int i = 1; i <= m; i++) if(bel[u[i]] != bel[v[i]]) add(bel[u[i]], bel[v[i]]); for(int i = 1; i <= tot; i++) if(!dp[i]) dfs(i); for(int i = 1; i <= n; i++) printf("%d ", dp[bel[i]]); return 0; }