BZOJ 2435:[Noi2011]道路修建(树型DP)

时间:2023-11-26 14:52:26

http://www.lydsy.com/JudgeOnline/problem.php?id=2435

题意:中文题意。

思路:很简单的树形DP,sz记录儿子有多少个和cur记录走的哪条弧,然后直接算就可以了。(时间有点紧)。

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1000010
struct Edge {
int v, w, nxt;
} edge[N*];
int head[N], tot, cur[N]; long long sz[N]; void Add(int u, int v, int w) {
edge[tot] = (Edge) {v, w, head[u]}; head[u] = tot++;
edge[tot] = (Edge) {u, w, head[v]}; head[v] = tot++;
} void DFS(int u, int fa) {
sz[u] = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(v == fa) continue;
cur[v] = i;
DFS(v, u);
sz[u] += sz[v];
}
} int main() {
int n;
while(~scanf("%d", &n)) {
tot = ;
memset(head, -, sizeof(head));
memset(sz, , sizeof(sz));
for(int i = ; i < n; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
Add(u, v, w);
}
DFS(, -);
long long ans = ;
for(int i = ; i <= n; i++) {
ans += (long long)edge[cur[i]].w * abs(n - sz[i] - sz[i]);
}
printf("%lld\n", ans);
}
return ;
}