usingnamespacestd; int f[16005], s[16005], head[40000], tot, ans = INT_MIN;
structedge{ int to, nxt; } e[40000];
voidadd(int u, int v){ e[++tot] = {v, head[u]}; head[u] = tot; }
voiddfs(int u, int fa){ f[u] = s[u]; for (int i = head[u]; i; i = e[i]. nxt) { int v = e[i].to; if (v == fa) continue; dfs(v, u); f[u] += max(f[v], 0); } ans = max(ans, f[u]); }
intmain(int argc, char *argv[]){ ios::sync_with_stdio(false); int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> s[i]; } int u, v; for (int i = 0; i < n - 1; ++i) { cin >> u >> v; add(u, v); add(v, u); } dfs(1, 0); cout << ans << endl; return0; }
洛谷 p1613 跑路
题目大意,图结构,如果i到j的距离为$2^k$千米,那么只需要1s时间。
$n \le 50, m \le 10000$
因为涉及到$2^k$,因此为倍增算法,先进行预处理,状态表示f[i][j][k]表示i到j有一条距离为$2^k$的边。 $$ f[i][j][k] = f[i][l][k - 1] && f[l][j][k - 1] \ 1 \le l \le n $$