1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #include <bits/stdc++.h> using namespace std; const int N = 4e4 + 5,M = 3e3 + 5,inf = 0x7f7f7f7f; template<typename T> inline bool ckmax(T &x,const T &y) { return (x < y) && (x = y,true);} int n,k; int a[N]; vector<int> G[N]; int f[N][M],g[N][M];
int sze[N],mxsz[N],rt; bool sgn[N]; void findroot(int x,int S,int fa) { sze[x] = 1;mxsz[x] = 0; for(auto y : G[x]) { if(y == fa || sgn[y]) continue; findroot(y,S,x); sze[x] += sze[y]; mxsz[x] = max(mxsz[x],sze[y]); } mxsz[x] = max(mxsz[x],S - sze[x]); if(mxsz[x] < mxsz[rt]) rt = x; } int dfstime; int dfn1[N],id1[N]; int dfn2[N],id2[N]; vector<int> Vs; int dep[N],wdep[N]; void dfs1(int x,int fa) { sze[x] = 1;Vs.push_back(x); dfn1[x] = ++dfstime;id1[dfn1[x]] = x; for(auto y : G[x]) if(y != fa && !sgn[y]) dep[y] = dep[x] + 1,wdep[y] = wdep[x] + a[y],dfs1(y,x),sze[x] += sze[y]; } void dfs2(int x,int fa) { for(auto y : G[x]) if(y != fa && !sgn[y]) dfs2(y,x); dfn2[x] = ++dfstime;id2[dfn2[x]] = x; } int Ans[N]; void Calc(int u) { dfstime = 0;Vs.clear(); wdep[u] = a[u];dep[u] = 1; dfs1(u,0);dfstime = 0; dfs2(u,0); if(Vs.size() < k) return; for(int i = 0;i <= Vs.size() + 1;i++) for(int j = 0;j <= k;j++) f[i][j] = g[i][j] = -inf; f[0][0] = 0; for(int i = 1;i <= Vs.size();i++) { for(int j = 0;j <= k;j++) f[i][j] = f[i - sze[id2[i]]][j]; for(int j = 0;j < k;j++) ckmax(f[i][j + 1],f[i - 1][j] + a[id2[i]]); } g[Vs.size() + 1][0] = 0; for(int i = Vs.size();i >= 1;i--) { for(int j = 0;j <= k;j++) g[i][j] = g[i + sze[id1[i]]][j]; for(int j = 0;j < k;j++) ckmax(g[i][j + 1],g[i + 1][j] + a[id1[i]]); } for(auto v : Vs) { int rest = k - dep[v]; for(int i = 0;i <= rest;i++) ckmax(Ans[v],f[dfn2[v] - sze[v]][i] + g[dfn1[v] + 1][rest - i] + wdep[v]); } } void Divide(int x,int S) { Calc(x); sgn[x] = true; for(auto y : G[x]) { if(sgn[y]) continue; rt = 0; int tmp = sze[y] > sze[x] ? S - sze[x] : sze[y]; findroot(y,tmp,x); Divide(rt,tmp); } } int main() { cin >> n >> k; for(int i = 1;i <= n;i++) cin >> a[i]; for(int i = 1,u,v;i < n;i++) cin >> u >> v,G[u].push_back(v),G[v].push_back(u); rt = 0;mxsz[0] = 1e9; findroot(1,n,0); Divide(rt,n); for(int i = 1;i <= n;i++) cout << Ans[i] << ' '; return 0; }
|