BZOJ 3727: PA2014 Final Zadanie 树形DP
非常有趣的一道题....
code:
#include <cstdio> #include <string> #include <algorithm> using namespace std; namespace IO { void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); } }; #define ll long long const int N=301000; int n,edges; ll sum,s[N]; int b[N],hd[N],to[N<<1],nex[N<<1],fa[N]; void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void dfs(int u) { for(int i=hd[u];i;i=nex[i]) { if(to[i]!=fa[u]) { fa[to[i]]=u; dfs(to[i]); } } } void solve(int u) { for(int i=hd[u];i;i=nex[i]) { if(to[i]!=fa[u]) { s[to[i]]=(sum+b[u]-b[to[i]])>>1; solve(to[i]); } } } int main() { // IO::setIO("input"); int i,j; scanf("%d",&n); for(i=1;i<n;++i) { int x,y; scanf("%d%d",&x,&y); add(x,y),add(y,x); } for(i=1;i<=n;++i) scanf("%d",&b[i]); dfs(1); sum=b[1]<<1; for(i=2;i<=n;++i) sum+=b[i]-b[fa[i]]; sum/=(n-1); s[1]=sum; solve(1); ll a; for(i=1;i<=n;++i) { a=s[i]; for(j=hd[i];j;j=nex[j]) if(to[j]!=fa[i]) a-=s[to[j]]; printf("%lld%c",a,(i==n)?'\n':' '); } return 0; }