[Usaco 2012 Feb]Nearby Cows
题目描述
FJ发现他的牛经常跑到附近的草地去吃草,FJ准备给每个草地种足够的草供这个草地以及附近草地的奶牛来吃。FJ有N个草地(1<=N<=100000),有N-1条双向道路连接这些草地,FJ精心设计了这些道路使每两个草地有且仅有一条简单路径连接。第i个草场有Ci头牛,有时候奶牛会走过K条道路到其他草地吃草。FJ想知道每个草场最多可能有的奶牛数量Mi,即所有走过K条道路后可能到达i的奶牛总数。
输入格式
Line 1: Two space-separated integers, N and K.
Lines 2..N: Each line contains two space-separated integers, i and j (1 <= i,j <= N) indicating that fields i and j are directly connected by a trail.
Lines N+1..2N:
Line N+i contains the integer C(i). (0 <= C(i) <= 1000)
输出格式
Lines 1..N: Line i should contain the value of M(i).
如果我们设dp(x)表示最多走k条路可以到达x的奶牛数,那么我们就不知道这dp(x)头奶牛里面多少是刚好走了k条路的,就不能更新相连的节点。我们唯一的更新dp数组的方法就是暴力往上走k步然后往下走k步。最坏的情况时间复杂度为O(N^2)——如果直径长度小于等于k的话。一般情况大概是O(NK * ∑degree[i]),很好卡的(其中degree表示节点的度数)。
考虑改变状态。既然我们需要知道有多少奶牛走了k步刚好走到x甚至更多的信息,我们不妨扩展一下状态:
设dp(i,j)表示刚好走了j步到达i节点的奶牛个数。由于整个图是一棵树,显然答案具有传递性。具体为:走d步到达x点的奶牛个数=走d-1步到达 ( 走1步到达x节点的 ) 节点的奶牛个数之和。那么答案就分成了两部分:一部分为当前子树中走过来的奶牛个数,另一部分为除了当前子树之外的点中走过来的奶牛个数。
设val(u)表示节点u原有的奶牛个数,并且设u有q个儿子。
先考虑第一种,那么可以写出状态转移方程:
\]
其中1≤i≤k。初始化dp(u,0)=val(u)。
再考虑第二种。先写出大概的方程:
\]
然而经过细心观察(或者直接提交)发现,这个方程是错的!为什么呢?因为dp(u,i-1)中显然有dp(son(x),i-2)的部分,然而这dp(son(x),i-2)头奶牛显然与son(x)的距离为1,而上面的方程显然把这个距离算成了3。由于我们在第一个方程中就已经计算了这一部分,所以我们考虑把这一部分给去掉。那么修改状态转移方程:
\]
然而经过细心观察(或者直接提交)发现,这个方程还是错的!为什么呢?其实是一个小细节,当i=1时后面那一坨是没有意义的。一是因为可能造成RE,二是跟son(x)距离为1的son(x)的子节点不能走i-1步到达u。特判一下即可。
* 代码中用m代替了k(个人习惯)
* 不开long long见祖宗
时间复杂度为O(NK)
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 100001
#define maxm 21
using namespace std;
struct edge{
int to,next;
edge(){}
edge(const int &_to,const int &_next){ to=_to,next=_next; }
}e[maxn<<1];
int head[maxn],k;
long long dp[maxn][maxm];
int n,m,val[maxn];
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
inline void add(const int &u,const int &v){ e[k]=edge(v,head[u]),head[u]=k++; }
void dfs1(int u,int pre){
dp[u][0]=val[u];
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==pre) continue;
dfs1(v,u);
for(register int i=1;i<=m;i++) dp[u][i]+=dp[v][i-1];
}
}
void dfs2(int u,int pre){
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==pre) continue;
for(register int i=m;i>=1;i--) dp[v][i]+=dp[u][i-1]-(i==1?0:dp[v][i-2]);
dfs2(v,u);
}
}
int main(){
memset(head,-1,sizeof head);
n=read(),m=read();
for(register int i=1;i<n;i++){
int u=read(),v=read();
add(u,v),add(v,u);
}
for(register int i=1;i<=n;i++) val[i]=read();
dfs1(1,0),dfs2(1,0);
for(register int i=1;i<=n;i++){
long long sum=0;
for(register int j=0;j<=m;j++) sum+=dp[i][j];
printf("%lld\n",sum);
}
return 0;
}
[Usaco 2012 Feb]Nearby Cows的更多相关文章
- 【bzoj2591】[Usaco 2012 Feb]Nearby Cows 树形dp
题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...
- USACO翻译:USACO 2012 FEB Silver三题
USACO 2012 FEB SILVER 一.题目概览 中文题目名称 矩形草地 奶牛IDs 搬家 英文题目名称 planting cowids relocate 可执行文件名 planting co ...
- USACO 2012 Feb Cow Coupons
2590: [Usaco2012 Feb]Cow Coupons Time Limit: 10 Sec Memory Limit: 128 MB Submit: 349 Solved: 181 [Su ...
- [USACO 2012 Feb Gold] Cow Coupons【贪心 堆】
传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=118 传送门2:http://www.lydsy.com/JudgeOn ...
- [Usaco 2012 Feb]Cow coupons牛券:反悔型贪心
Description Farmer John needs new cows! There are N cows for sale (1 <= N <= 50,000), ...
- USACO翻译:USACO 2012 JAN三题(2)
USACO 2012 JAN(题目二) 一.题目概览 中文题目名称 叠干草 分干草 奶牛联盟 英文题目名称 stacking baleshare cowrun 可执行文件名 stacking bale ...
- USACO翻译:USACO 2012 JAN三题(1)
USACO 2012 JAN(题目一) 一.题目概览 中文题目名称 礼物 配送路线 游戏组合技 英文题目名称 gifts delivery combos 可执行文件名 gifts delivery c ...
- USACO翻译:USACO 2014 FEB SILVER 三题
USACO 2014 FEB SILVER 一.题目概览 中文题目名称 自动打字 路障 神秘代码 英文题目名称 auto rblock scode 可执行文件名 auto rblock scode 输 ...
- 【USACO 2012 Open】Running Laps(树状数组)
53 奶牛赛跑 约翰有 N 头奶牛,他为这些奶牛准备了一个周长为 C 的环形跑牛场.所有奶牛从起点同时起跑,奶牛在比赛中总是以匀速前进的,第 i 头牛的速度为 Vi.只要有一头奶牛跑完 L 圈之后,比 ...
随机推荐
- 08-flask-使用pymysql
代码 from flask import Flask from flask import render_template import pymysql # 创建flask对象 app = Flask( ...
- Linux OOM Killer造成数据库访问异常排查
服务器上的服务器访问异常,查看/va/log/messages发现如下: Sep 22 16:08:21 safeserver kernel: java invoked oom-killer: gfp ...
- Flink开发中的问题
1. 流与批处理的区别 流处理系统 流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一个节点,由下一个节点继续处理. 批处理系统 批处理系统, ...
- LightningChart解决方案:XY和3D图表(Polymer Char GPC-IR®-工程案例)
LightningChart解决方案:XY和3D图表(Polymer Char GPC-IR-工程案例) 所在行业:石化公司成立时间:1992年LightningChart解决方案:XY和3D图表 P ...
- 一劳永逸,解决基于 keep-alive 的后台多级路由缓存问题
用过 vue-element-admin 的同学一定很清楚,路由的配置直接关系侧边栏导航菜单的展示,也得益于这种设计思路,几乎大部分后台框架都采用这个方案,当然也包括了我写的 Fantastic-ad ...
- Python 炫技操作:安装包的八种方法,你知道吗?
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 1. 使用 easy_install easy_install 这应该是最古老的包安装方式了,目前基 ...
- Java基础:String类详解,案例用户登录实现,案例手机号截取实现,案例敏感词替换实现;StringBuilder类详解,StringBuilder和String相互转换,附练习案例.
1.API 1.1 API概述-帮助文档的使用 什么是API API (Application Programming Interface) :应用程序编程接口 java中的API 指的就是 JDK ...
- mssql不存在便插入存在不执行操作
前言 参考:https://www.jb51.cc/mssql/76911.html 在mssql中,在记录不存在时插入记录,如果存在则不执行操作 数据库 相关语句 --创建表 CREATE TABL ...
- 记录第一次使用Vivado——以全加器为例子
从altera转战xilinx,经典的FPGA到ZYNQ系列,第一站就是先熟悉编译软件Vivado.我就直接跳过软件安装部分了,如有疑问,可以在评论区提出来,我看到了就帮你解答. 首先是是打开界面 然 ...
- 常用java自带命令概览
ref:http://www.hollischuang.com/archives/308 一.常用命令 jps: 查看本机的Java中进程信息. jstack: 打印线程的执行栈信息. jmap: 打 ...