P2986 [USACO10MAR]伟大的奶牛聚集

Posted -ackerman

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2986 [USACO10MAR]伟大的奶牛聚集相关的知识,希望对你有一定的参考价值。

题意:

给一棵 n 个点的边 + 点权树,求带权重? 
 

思路:

其实这题和之前那个 Sta 有点像,我们同样只需要预处理出一个 f[u] 代表以 u 为集合点的方便程度,那么我们就可以O(1)的转移了

假设 v 是 u 的儿子,f[v] = f[u] - (siz[v] * len) + (n - siz[v] ) * len = f[u] + (n - 2 * siz[v] )  * len

这题有一个坑,就是你的INF得开的特别大,不然你就没有 100 了

#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>

#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
#define ls nod<<1
#define rs (nod<<1)+1

const double eps = 1e-10;
const int maxn = 1e5 + 10;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct edge {
    int v,nxt,w;
}e[maxn << 1];

int head[maxn];
LL siz[maxn],dis[maxn],num[maxn],f[maxn];
int cnt,n;
LL ans;

inline void add_edge(int u,int v,int w) {
    e[++cnt].v = v;
    e[cnt].w = w;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}

inline void dfs(int u,int f) {
    siz[u] = num[u];
    for (int i = head[u];~i;i = e[i].nxt) {
        int v = e[i].v,len = e[i].w;
        if (v == f)
            continue;
        dis[v] = dis[u] + len;
        dfs(v,u);
        siz[u] += siz[v];
    }
}

inline void func(int x,int fa) {
    for (int i = head[x];~i;i = e[i].nxt) {
        int v = e[i].v,len = e[i].w;
        if (v == fa)
            continue;
        f[v] = f[x] - siz[v] * len + (siz[1] - siz[v]) * len;
        func(v,x);
    }
}

int main() {
    memset(head,-1, sizeof(head));
    cnt = 0;
    ans = INF;
    cin >> n;
    for (int i = 1;i <= n;i++) {
        cin >> num[i];
    }
    for (int i = 1;i < n;i++) {
        int u,v,w;
        cin >> u >> v >> w;
        add_edge(u,v,w);
        add_edge(v,u,w);
    }
    dfs(1,0);
    for (int i = 1;i <= n;i++) {
        f[1] += (dis[i]*num[i]);
    }
    func(1,0);
    for (int i = 1;i <= n;i++) {
        ans = min(ans,f[i]);
    }
    cout << ans << endl;
    return 0;
}

 

以上是关于P2986 [USACO10MAR]伟大的奶牛聚集的主要内容,如果未能解决你的问题,请参考以下文章

题解 P2986 [USACO10MAR]伟大的奶牛聚集

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

洛谷 P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…

P2986 [USACO10MAR]伟大的奶牛聚集

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat…