标签:struct ack 最小 include cout ref turn span 题意
这个题过于水…
考虑单独的以 \(u\) 为根的一个子树,我们假设 \(u\) 的所有子节点 \(v\) 形成的子树已经满足条件(即 \(v\) 到 \(v\) 的叶子节点的距离经过 \(f[v]\) 次改变已经达到了深度相等的状态),我们现在只需改变所有 \(e\{u, v\}\) 的值使得 \(u\) 子树的所有叶子节点深度相同,很显然,是让所有深度最小的叶子节点变成深度最大的叶子节点即可,当前改变的总代价就是 \(\sum (MAX-d[v]) + \sum f[v]\),\(MAX\) 为最深叶子节点的深度。
#include<bits/stdc++.h>
using namespace std;
const int N = 500050;
typedef long long ll;
struct node{
ll nxt, to, dis;
}edge[N << 1];
ll head[N], num;
void build(ll from, ll to, ll dis){
edge[++num].nxt = head[from];
edge[num].to = to;
edge[num].dis = dis;
head[from] = num;
}
ll f[N], MAX[N];
void dfs(ll u, ll fa){
vector<int> G; f[u] = 0; MAX[u] = 0;
for(ll i=head[u]; i; i=edge[i].nxt){
ll v = edge[i].to, d = edge[i].dis;
if(v == fa) continue;
dfs(v, u);
G.push_back(MAX[v] + d);
MAX[u] = max(MAX[v] + d, MAX[u]);
f[u] += f[v];
}
for(int x : G){
f[u] += MAX[u] - x;
}
}
ll n, s;
int main(){
cin >> n >> s;
for(ll i=1; i<=n-1; i++){
ll u, v, d; cin >> u >> v >> d;
build(u, v, d); build(v, u, d);
}
dfs(s, 0);
cout << f[s];
return 0;
}
写完记得随便造组数据查一下…不然后果有可能是第一遍全 \(WA\)…
标签:struct ack 最小 include cout ref turn span 题意
原文地址:https://www.cnblogs.com/alecli/p/10060729.html