bzoj 3252 攻略(長鏈剖分 + 貪心)
阿新 • • 發佈:2018-12-30
#include <bits/stdc++.h> using namespace std; const int maxn = 300000 + 100; inline int read() { int ch, x = 0, f = 1;ch = getchar(); while((ch < '0' || ch > '9') && ch != '-') ch = getchar(); ch == '-' ? f = -1, ch = getchar() : 0; while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return f * x; } int n, m; int val[maxn]; struct Edge { int to, nxt; Edge() {} Edge(int _to, int _nxt):to(_to), nxt(_nxt) {} }E[maxn << 1]; priority_queue<long long>Q; int fa[maxn], son[maxn], top[maxn], h[maxn], cnt; long long max_dep[maxn]; inline void add_edge(int u, int v) { E[++cnt] = Edge(v, h[u]), h[u] = cnt; E[++cnt] = Edge(u, h[v]), h[v] = cnt; } long long ans; void dfs1(int x) { max_dep[x] = val[x]; son[x] = 0; for(int i = h[x]; ~i; i = E[i].nxt) { int to = E[i].to; if(to == fa[x]) continue; fa[to] = x; dfs1(to); max_dep[x] = max(max_dep[x], max_dep[to] + val[x]); if(max_dep[to] > max_dep[son[x]]) son[x] = to; } } void dfs2(int x) { if(x == son[fa[x]]) top[x] = top[fa[x]]; else top[x] = x; if(son[x]) dfs2(son[x]); for(int i = h[x]; ~i; i = E[i].nxt) { int to = E[i].to; if(to == son[x] || to == fa[x]) continue; dfs2(to); } } signed main() { memset(h, -1, sizeof(h)); n = read(), m = read(); for(int i = 1; i <= n; i++) val[i] = read(); for(int i = 1; i < n; i++) add_edge(read(), read()); dfs1(1); dfs2(1); for(int i = 1; i <= n;i ++) { if(top[i] == i) Q.push(max_dep[i]); } int j = 1; while(!Q.empty() && j <= m) { ans += Q.top(); Q.pop(); j++; } printf("%lld\n", ans); return 0; }