1015 [USACO 2010 Mar G]Great Cow Gathering 换根DP

链接:https://ac.nowcoder.com/acm/contest/25022/1015
来源:牛客网

题目描述

Bessie is planning the annual Great Cow Gathering for cows all across the country and, of course, she would like to choose the most convenient location for the gathering to take place.
Each cow lives in one of N (1 <= N <= 100,000) different barns (conveniently numbered 1..N) which are connected by N-1 roads in such a way that it is possible to get from any barn to any other barn via the roads. Road i connects barns AiA_iAi and BiB_iBi (1 <= AiA_iAi <= N; 1 <= BiB_iBi <= N) and has length LiL_iLi (1 <= LiL_iLi <= 1,000). The Great Cow Gathering can be held at any one of these N barns. Moreover, barn i has CiC_iCi (0 <= CiC_iCi <= 1,000) cows living in it.
When choosing the barn in which to hold the Cow Gathering, Bessie wishes to maximize the convenience (which is to say minimize the inconvenience) of the chosen location. The inconvenience of choosing barn X for the gathering is the sum of the distances all of the cows need to travel to reach barn X (i.e., if the distance from barn i to barn X is 20, then the travel distance is Ci∗20C_i*20Ci20). Help Bessie choose the most convenient location for the Great Cow Gathering.
Consider a country with five barns with [various capacities] connected by various roads of varying lengths. In this set of barns, neither barn 3 nor barn 4 houses any cows.
      1     3     4     5
      @--1--@--3--@--3--@[2]
     [1]    |
            2
            |
            @[1]
            2
Bessie can hold the Gathering in any of five barns; here is the table of inconveniences calculated for each possible location:  Gather      ----- Inconvenience ------
  Location    B1  B2  B3  B4  B5   Total
     1         0   3   0   0  14    17
     2         3   0   0   0  16    19
     3         1   2   0   0  12    15
     4         4   5   0   0   6    15
     5         7   8   0   0   0    15
If Bessie holds the gathering in barn 1, then the inconveniences from each barn are:
      Barn 1     0 -- no travel time there!
      Barn 2     3 -- total travel distance is 2+1=3  x 1 cow = 3
      Barn 3     0 -- no cows there!
      Barn 4     0 -- no cows there!
      Barn 5    14 -- total travel distance is 3+3+1=7 x 2 cows = 14
So the total inconvenience is 17.
The best possible convenience is 15, achievable at by holding the
Gathering at barns 3, 4, or 5.


输入描述:

* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains a single integer: CiC_iCi
* Lines N+2..2*N: Line i+N+1 contains three integers: AiA_iAi, BiB_iBi, and LiL_iLi

输出描述:

* Line 1: The minimum inconvenience possible
示例1

输入

复制
5 
1 
1 
0 
0 
2 
1 3 1 
2 3 2 
3 4 3 
4 5 3 

输出

复制
15

 

分析

题意是每个地点都有a 个人,x到y距离为z。问聚集到哪个点所花费的总路程最少。

设f[u] 为所有人聚集到u 点的总路程

树形DP:

f[u] += f[v] + sz[v] * w[i];

换根DP

先让 v 到 u 的总路程从 u 中删除

f[u] -= sz[v] * w[i];

再让所有节点的人从u 走到 v(由于换根DP在处理子节点之前已经把它的父节点处理过了,所以f[u] 已经表示所有人都走到 u 的 总路程,接下来只要让这些人走到 v 就好了)

f[v] += f[u] +(tot - sz[v]) * w[i] 

 

//-------------------------代码----------------------------

//#define int ll
const int N = 2e5+10;
int n,m;
int e[N],ne[N],w[N],h[N],idx;
int a[N],d[N],sz[N];//聚集到这个点的不方便度
ll f[N];
void add(int a,int b,int c) {
    e[idx] = b,ne[idx] = h[a],w[idx] = c,h[a] = idx++;
}

void dfs1(int u,int fa) {
    f[u] = 0;
    sz[u] = a[u];
    for(int i = h[u];~i;i=ne[i]) {
        int v = e[i];
        if(v == fa) continue;
        dfs1(v,u);
        f[u] += f[v]+ 1ll * sz[v] * w[i];
        sz[u] += sz[v];
    }
    //f[u] -= f[v] + 1ll * sz[v] * w[i];
    //f[v] += (f[u] - f[v] + 1ll * sz[v] * w[i]) * w[i];
//     f[v] += (f[u] - f[v] * w[i]) * w[i];
}

void dfs2(int u,int fa) {
    for(int i = h[u];~i;i=ne[i]) {
        int v = e[i];
        if(v == fa) continue;
        f[v] = (f[u] - 1ll * sz[v] * w[i]) + 1ll * (sz[1] - sz[v]) * w[i];
        dfs2(v,u);
    }
}

void solve()
{
//    cin>>n>>m;
    ms(h,-1);
    cin>>n;
    fo(i,1,n) {
        cin>>a[i];
    }
    fo(i,1,n-1) {
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);d[x] ++ ;
        add(y,x,z);d[y] ++ ;
    }
    dfs1(1,-1);
    dfs2(1,-1);
    ll mn = INF;
    for(int i = 1;i<=n;i++) {
        mn = min(mn,f[i]);
    }
    cout<<mn<<endl;
}

signed main(){
    AC();
    clapping();TLE;

//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-04 18:09  er007  阅读(19)  评论(0编辑  收藏  举报