码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2007]时态同步

时间:2018-12-03 21:01:46      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:struct   ack   最小   include   cout   ref   turn   span   题意   

题意

Here

思考

这个题过于水…

考虑单独的以 \(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\)

[ZJOI2007]时态同步

标签:struct   ack   最小   include   cout   ref   turn   span   题意   

原文地址:https://www.cnblogs.com/alecli/p/10060729.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!