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

BZOJ 1060 ZJOI 2007 时态同步 树形DP

时间:2014-12-10 14:16:42      阅读:280      评论:0      收藏:0      [点我收藏+]

标签:bzoj   zjoi2007   搞笑系列   树形dp   动态规划   

题目大意:给出一个有根树,树上的边有边权。现在可以将一个边的边权的值+1,要想使得根节点到所有叶子节点的距离相等,最少需要多少个+1操作。


思路:当只考虑以一个节点为根的子树的时候,就必须要保证这个根节点到所有这个子树中的叶子节点的距离相等,才能保证最终根节点到所有叶子节点的距离都相等。所以就深搜一次,对于每个节点求出到这个节点的最长距离,将所有其他的边加成这个最长距离,记录答案。

但是这样并不能AC,因为标称是错的,它没有开long long ,于是乎我们也要开int才能AC。。-、-


CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 500010
using namespace std;
#define max(a,b) ((a) > (b) ? (a):(b))
 
int points,root;
int head[MAX],total;
int next[MAX << 1],aim[MAX << 1],length[MAX << 1];
 
long long ans;
 
inline void Add(int x,int y,int len)
{
    next[++total] = head[x];
    aim[total] = y;
    length[total] = len;
    head[x] = total;
}
 
int DFS(int x,int last)
{
    int max_length = 0;
    long long sum = 0,cnt = 0;
    for(int i = head[x],l; i; i = next[i]) {
        if(aim[i] == last)  continue;
        ++cnt;
        l = DFS(aim[i],x) + length[i];       (这个l要开成int,不然就是WA)
        max_length = max(max_length,l);
        sum += l;
    }
    ans += (max_length * cnt - sum);
    return max_length;
}
 
int main()
{
    cin >> points >> root;
    for(int x,y,z,i = 1; i < points; ++i) {
        scanf("%d%d%d",&x,&y,&z);
        Add(x,y,z),Add(y,x,z);
    }
    DFS(root,0);
    printf("%lld\n",ans);
    return 0;
}


BZOJ 1060 ZJOI 2007 时态同步 树形DP

标签:bzoj   zjoi2007   搞笑系列   树形dp   动态规划   

原文地址:http://blog.csdn.net/jiangyuze831/article/details/41844745

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