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

原文地址:https://www.cnblogs.com/-Ackerman/p/12339717.html

时间: 2024-11-09 03:01:23

P2986 [USACO10MAR]伟大的奶牛聚集的相关文章

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

题解 P2986 [USACO10MAR]伟大的奶牛聚集 题目链接 很好的一道树形dp的题目,我们观察每一个点i的答案,发现答案 f[i] 由两部分组成: A1.i所有子树中的犇集中到i点 A2.除了i的子树中的所有犇集中到i的父亲节点,再走到i点 f[i] = A1 + A2 我们发现i的答案和i的孩子有关,也和i的父亲有关.一般这样的问题用两次dfs就可以解决.(由于选谁是根节点都无所谓,以下以1号节点为根) 第一次dfs我们求出每一个点的 f[i], 意思是以i为根节点的子树中的牛集中到i

洛谷 P2986 [USACO10MAR]伟大的奶牛聚集(树形动规)

题目描述 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. Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会

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

题目描述 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. Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会

P2986 [USACO10MAR]伟大的奶牛聚集(思维,dp)

题目描述 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. Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会

[USACO10MAR]伟大的奶牛聚集

[USACO10MAR]伟大的奶牛聚集 Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来举办这次集会. 每个奶牛居住在 N(1<=N<=100,000) 个农场中的一个,这些农场由N-1条道路连接,并且从任意一个农场都能够到达另外一个农场.道路i连接农场A_i和B_i(1 <= A_i <=N; 1 <= B_i <= N),长度为L_i(1 <= L_i <= 1,000).集会可以在N个农场中的

BZOJ 1827 洛谷 2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gather

[题解] 很容易想到暴力做法,枚举每个点,然后对于每个点O(N)遍历整棵树计算答案.这样整个效率是O(N^2)的,显然不行. 我们考虑如果已知当前某个点的答案,如何快速计算它的儿子的答案. 显然选择它的儿子作为集合点,它的儿子的子树内的奶牛可以少走当前点到儿子节点的距离dis,不在它儿子的子树内的奶牛要多走dis. 那么我们维护每个节点的子树内的奶牛总数(即点权和),就可以快速进行计算了.效率O(N). 1 #include<cstdio> 2 #include<algorithm>

[USACO10MAR] 伟大的奶牛聚集 - 树形dp

每个点有重数,求到所有点距离最小的点 就是魔改的重心了 #include <bits/stdc++.h> using namespace std; #define int long long const int N = 1000005; vector <pair<int,int> > g[N]; int siz[N],f[N],vis[N],sum[N],c[N],n,m,t1,t2,t3,tot; void dfs1(int p) { vis[p]=1; siz[p]

洛谷 P2986 [USACO10MAR]Great Cow Gat…(树形dp+容斥原理)

P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat… 题目描述 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 on

饥饿的奶牛(洛谷 1868)

题目描述 有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字. 现用汉语翻译为: 有N个区间,每个区间x,y表示提供的x~y共y-x+1堆优质牧草.你可以选择任意区间但不能有重复的部分. 对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他. 输入输出格式 输入格式: 第一行,N,如题 接下来N行,每行一个数x,y,如题 输出格式: 一个数,最多的区间数 输入输出样例 输入样例#1: 3 1 3 7 8 3 4 输出样例#1: 5 说明 1<=n<=15