传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3677
【题解】
我们发现这样一个结论:如果把某个点作为根,那么蓝线一定是fa-x-son这种情况。
而且一个点作为只能作为一条蓝线的中点。
那么可以dp:
令f[i][0/1]表示x是否为蓝线中点的max值。
具体解释:
1. i不是蓝线中点:那么可能从下面的所有蓝线中点连接上来取个max即可。
2. i是蓝线中点:那么我们去掉一个连接的点,把它改为连线(就是连一条son->i的蓝线),那么i就是蓝线中点了。
那么我们对每个根做一个dp,就是O(n^2)的,可以有50多分?
# include <stdio.h> # include <string.h> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n; int head[M], nxt[M], to[M], w[M], tot=0; inline void add(int u, int v, int _w) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; w[tot] = _w; } inline void adde(int u, int v, int _w) { add(u, v, _w); add(v, u, _w); } ll f[M][2], ans; inline void dfs(int x, int fa) { f[x][0] = 0, f[x][1] = -1e18; for (int i=head[x]; i; i=nxt[i]) { if(to[i] == fa) continue; dfs(to[i], x); f[x][0] += max(f[to[i]][0], f[to[i]][1] + w[i]); f[x][1] = max(f[x][1], -max(f[to[i]][0], f[to[i]][1] + w[i]) + f[to[i]][0] + w[i]); } f[x][1] += f[x][0]; } int main() { scanf("%d", &n); for (int i=1, u, v, _w; i<n; ++i) { scanf("%d%d%d", &u, &v, &_w); adde(u, v, _w); } for (int i=1; i<=n; ++i) { dfs(i, 0); ans = max(ans, f[i][0]); } printf("%lld\n", ans); return 0; }