题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3278

题意:给出一棵树,找出一个不大于长度为m的链,使得其他点到该链的长度之和最小。

预处理出以下数组:

(1)downSum[u]:u的所有孩子到达u的距离,downCnt[u]:u子树节点个数;

(2)upSum[u]:除u子树的节点外其他节点到达u的距离;upCnt[u]:除u子树的节点个数。

树形DP时,竖线形状的比较简单,我们用dp[u][L]表示以u为子树,向下有一条长度为L的链的最小代价;然后dp[u][m]+upSum[u]就是答案;对于折线形状的,设以u的两个孩子v1、v2组成,则答案为upSum[u]+downSum[u]+dp[v1][j-1]-downSum[v1]-downCnt[v1]+dp[v2][m-1-j]-downSum[v2]-downCnt[v2],因此只要维护upSum[u]+downSum[u]+dp[v1][j-1]-downSum[v1]-downCnt[v1]的最小值即可。

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
int ans,downcnt[],downsum[];
int upsum[],upcnt[];
int n,m;
int tot,go[],first[],next[];
int dp[][],f[][];
void insert(int x,int y){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
}
void add(int x,int y){
insert(x,y);insert(y,x);
}
void dfs(int x,int fa){
downcnt[x]=;
downsum[x]=;
upcnt[x]=;
upsum[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
dfs(pur,x);
downcnt[x]+=downcnt[pur];
downsum[x]+=downsum[pur]+downcnt[pur];
}
upcnt[x]=n-downcnt[x];
}
void Dfs(int x,int fa){
if (fa!=){
upcnt[x]=n-downcnt[x];
upsum[x]=upsum[fa]+upcnt[fa]+downsum[fa]-downsum[x]-downcnt[fa]++(downcnt[fa]--downcnt[x])*+;
}else upsum[x]=upcnt[x]=;
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
Dfs(pur,x);
}
}
void DP(int x,int fa){
for (int i=;i<=m+;i++)
dp[x][i]=downsum[x],f[x][i]=downsum[x]+upsum[x];
for (int i=first[x];i;i=next[i]){
int pur=go[i];
if (pur==fa) continue;
DP(pur,x);
for (int j=;j<=m;j++){
dp[x][j]=std::min(dp[x][j],dp[pur][j-]+downsum[x]-downsum[pur]-downcnt[pur]);
if (m-j->=) ans=std::min(ans,f[x][j]+dp[pur][m--j]-downsum[pur]-downcnt[pur]);
}
for (int j=;j<=m;j++){
f[x][j]=std::min(f[x][j],upsum[x]+downsum[x]+dp[pur][j-]-downsum[pur]-downcnt[pur]);
}
}
ans=std::min(ans,dp[x][m]+upsum[x]);
}
int main(){
while (scanf("%d%d",&n,&m)!=EOF){
if (n==&&m==) return ;
tot=;for (int i=;i<=n;i++) first[i]=;
for (int i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
x++;y++;
add(x,y);
}
ans=0x7fffffff;
dfs(,);
Dfs(,);
DP(,);
printf("%d\n",ans);
}
}

ZOJ 3188 ZOJ 3188 Treeland Exhibition(树形DP)的更多相关文章

  1. CF 219 D:Choosing Capital for Treeland(树形dp)

    D. Choosing Capital for Treeland 链接:http://codeforces.com/problemset/problem/219/D   The country Tre ...

  2. Codeforces 219D Choosing Capital for Treeland(树形DP)

    题目是给一张边有向的树形图.要选出首都的点,首都要都能走到其他点,因此要反转一些边的方向.问可以选哪几个点作为首都,使它们所需反转边的数量最少. 这题挺好想的,因为做过HDU2196. 首先就不妨设正 ...

  3. ZOJ 3949 Edge to the Root( 树形dp)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3949 题解:树dp真的很直觉,或者说dp真的很直觉.就上周末比赛时其实前一 ...

  4. ZOJ 3626 Treasure Hunt I(树形dp)

    Treasure Hunt I Time Limit: 2 Seconds      Memory Limit: 65536 KB Akiba is a dangerous country since ...

  5. ZOJ 3626 Treasure Hunt I (树形DP,常规)

    题意:给一棵树,一个人站在节点s,他有m天时间去获取各个节点上的权值,并且最后需要回到起点s,经过每条边需要消耗v天,问最少能收获多少权值? 思路: 常规的,注意还得跑回原地s. //#include ...

  6. 【codeforce 219D】 Choosing Capital for Treeland (树形DP)

    Choosing Capital for Treeland Description The country Treeland consists of n cities, some pairs of t ...

  7. Codeforces 490F Treeland Tour 树形dp

    Treeland Tour 离散化之后, 每个节点维护上升链和下降链, 感觉复杂度有点高, 为啥跑这么快.. #include<bits/stdc++.h> #define LL long ...

  8. CodeForces 219D Choosing Capital for Treeland (树形DP)

    题意:给一个树形图,n个节点,n-1条有向边,要求选一个节点作为根,使需要改变方向的边的数目最少.并输出所有可能作为根的点. 思路: 先随便一个点进行DFS,计算将每棵子树的边全部往下时,所需要的费用 ...

  9. Choosing Capital for Treeland CodeForces - 219D (树形DP)

    传送门 The country Treeland consists of n cities, some pairs of them are connected with unidirectional  ...

随机推荐

  1. logstash nginx 报ArgumentError: comparison of String with 5 failed

    80.82.78.38 [23/Sep/2016:05:36:18 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP ...

  2. cf437A The Child and Homework

    A. The Child and Homework time limit per test 1 second memory limit per test 256 megabytes input sta ...

  3. VS2012/2013编辑器问题

    1. Visual Studio 2013 'Could not evaluate Expression' Debugger Abnormality 解决办法:http://weblog.west-w ...

  4. XPath详解

     xPath技术   1 引入 问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!! 2 xPath作用 主要是用于快速获取所需的节点对象. 3 在dom4j中如何使用 ...

  5. 并发情况下synchronized死锁

    存在缺陷的代码: public class DataPropertyIdAndNameRepositoryImpl{ /** 发布标志 */ private volatile boolean publ ...

  6. 事关Animation Tree的工作随笔(二)

    上回说到,游戏项目中客观会遇到逻辑状态的复杂性和动画状态的单一性之间的矛盾,那么Animation Tree是如何解决这个问题的呢? 这又需要引入一个定律:就是逻辑状态无论有多么复杂,但一套逻辑状态组 ...

  7. (转) 值不能为空。参数名viewinfo(microsoft.sqlserver.management.sqlstudio.explorer)

    打开MSSQL 2008 R2的时候,展开数据库都显示以下的错误提示: 值不能为空.参数名viewinfo(microsoft.sqlserver.management.sqlstudio.explo ...

  8. Proguard 保留native methods的问题

    发现一个奇怪的问题,如果使用下面的配置来keep的话,native的方法还是被删掉了,百思不得其解. -keepclasseswithmembers class * {     native *; } ...

  9. 如何安装Windows Live Writer插件

    Windows Live Writer 是一个强大的离线博客编辑工具,通过它可以离线编辑内容丰富的博文.它不但支持微软的live space,还支持诸如Wordpress 这样的开源博客系统. Win ...

  10. 空值排序(oracle和sqlserver)

    oracle认为 null 最大. 升序排列,默认情况下,null值排后面. 降序排序,默认情况下,null值排前面. 改变空值办法: (1)用nvl函数或decode函数将null转换为一特定值 替 ...