BZOJ 1827 奶牛大集会

Posted on 2016-07-11 17:29  ziliuziliu  阅读(131)  评论(0编辑  收藏  举报

树型DP。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 200500
#define maxe 300500
#define inf 1000000007
using namespace std;
long long n,x,y,z,c[maxv],nume=0,g[maxv],val[maxv],sum=0,ans,dis[maxv];
struct edge
{
    long long v,w,nxt;
}e[maxe];
void addedge(long long u,long long v,long long w)
{
    e[++nume].v=v;
    e[nume].w=w;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void dfs1(long long x,long long fath)
{
    val[x]=c[x];
    for (long long i=g[x];i;i=e[i].nxt)
    {
        long long v=e[i].v;
        if (v!=fath)
        {
            dis[v]=dis[x]+e[i].w;
            dfs1(v,x);
            val[x]+=val[v];
        }
    }
}
void dfs2(long long x,long long fath,long long now)
{
    for (long long i=g[x];i;i=e[i].nxt)
    {
        long long v=e[i].v;
        if (v!=fath)
        {
            long long re=now-val[v]*e[i].w+(sum-val[v])*e[i].w;
            ans=min(ans,re);
            dfs2(v,x,re);
        }    
    }
}
int main()
{
    scanf("%lld",&n);
    for (long long i=1;i<=n;i++)
    {
        scanf("%lld",&c[i]);
        sum+=c[i];
    }
    for (long long i=1;i<=n-1;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        addedge(x,y,z);
        addedge(y,x,z);    
    }    
    dfs1(1,1);
    for (long long i=1;i<=n;i++)
        ans+=c[i]*dis[i];
    dfs2(1,1,ans);
    printf("%lld\n",ans);
    return 0;
}