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; 
}

  

posted @ 2019-12-25 14:59  EM-LGH  阅读(163)  评论(0编辑  收藏  举报