题目描述

Farmer John has noticed that his cows often move between nearby fields. Taking this into account, he wants to plant enough grass in each of his fields not only for the cows situated initially in that field, but also for cows visiting from nearby fields.

Specifically, FJ’s farm consists of N fields (1 <= N <= 100,000), where some pairs of fields are connected with bi-directional trails (N-1 of them in total). FJ has designed the farm so that between any two fields i and j, there is a unique path made up of trails connecting between i and j. Field i is home to C(i) cows, although cows sometimes move to a different field by crossing up to K trails (1 <= K <= 20).

FJ wants to plant enough grass in each field i to feed the maximum number of cows, M(i), that could possibly end up in that field — that is, the number of cows that can potentially reach field i by following at most K trails. Given the structure of FJ’s farm and the value of C(i) for each field i, please help FJ compute M(i) for every field i.

农民约翰已经注意到他的奶牛经常在附近的田野之间移动。考虑到这一点,他想在每一块土地上种上足够的草,不仅是为了最初在这片土地上的奶牛,而且是为了从附近的田地里去吃草的奶牛。

具体来说,FJ的农场由N块田野构成(1 <= n <= 100,000),每两块田野之间有一条无向边连接(总共n-1条边)。FJ设计了农场,任何两个田野i和j之间,有且只有一条路径连接i和j。第 i块田野是C(i)头牛的住所,尽管奶牛们有时会通过k条路到达其他不同的田野(1<=k<=20)。

FJ想在每块田野上种上够M(i)头奶牛吃的草。M(i)指能从其他点经过最多k步就能到达这个点的奶牛的个数。

现给出FJ的每一个田野的奶牛的数目,请帮助FJ计算每一块田野的M(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)

第一行:n和k;

后面n-1行:i和j(两块田野);

之后n行:1..n每一块的C(i);

输出格式:

  • Lines 1..N: Line i should contain the value of M(i).

n行:每行M(i);//i:1..2

输入输出样例

输入样例#1: 复制

6 2
5 1
3 6
2 4
2 1
3 2
1
2
3
4
5
6

输出样例#1: 复制

15
21
16
10
8
11

说明

There are 6 fields, with trails connecting (5,1), (3,6), (2,4), (2,1), and (3,2). Field i has C(i) = i cows.

Field 1 has M(1) = 15 cows within a distance of 2 trails, etc.

题目简述:给出一棵n个点的树,每个点上有C_i头牛,问每个点k步范围内各有多少头牛。

思路

树型dp + 简单容斥原理

  • 用$f[i][j]$表示距节点i的距离小于等于j的所有节点的权值和,即牛的数量
  • $son[i]$表示i的子节点数
  • 可以想到,将此状态转移至与自己连通的v节点的$f[v][j-1]$中,即 $f[i][j]=f[v][j-1]+c[i]$

但是,这样会有一部分重复计算。因为$f[v][j-1]$中还包括了点i与点i距离小于等于j-2的点

  • 只要再减掉重复位置,即$f[i][j-2]*(son[i]-1)$

$$f[i][j]=f[s][j-1]-f[i][j-2]*(son[i]-1)$$

代码

#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register int
using namespace std;
const int maxn=1e5+50;
inline int read(){
int x=0,w=1;
char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x*w;
}
struct data {
int to,nxt;
}edge[210001]; int head[maxn],tot;
int f[maxn][21],sons[maxn];
int n,k;
inline void add(int a,int b) {
edge[++tot].to=b;
edge[tot].nxt=head[a];
head[a]=tot;
edge[++tot].to=a;
edge[tot].nxt=head[b];
head[b]=tot;
sons[a]++; sons[b]++;
}
int main() {
re i,j,s;
n=read(),k=read();
int a,b;
for(i=1;i<n;++i) {
a=read(),b=read();
add(a,b);
}
for(i=1;i<=n;++i) f[i][0]=read();
for(j=1;j<=k;++j) for(i=1;i<=n;++i){
for(s=head[i];s;s=edge[s].nxt) f[i][j]+=f[edge[s].to][j-1];
if(j>1) f[i][j]-=(sons[i]-1)*f[i][j-2];
else f[i][1]+=f[i][0];
}
for(i=1;i<=n;++i) printf("%d\n",f[i][k]);
return 0;
}

【题解】Luogu p3047 [USACO12FEB]附近的牛Nearby Cows 树型dp的更多相关文章

  1. LUOGU P3047 [USACO12FEB]附近的牛Nearby Cows

    传送门 解题思路 树形dp,看到数据范围应该能想到是O(nk)级别的算法,进而就可以设出dp状态,dp[x][j]表示以x为根的子树,距离它为i的点的总和,第一遍dp首先自底向上,dp出每个节点的子树 ...

  2. 洛谷 P3047 [USACO12FEB]附近的牛Nearby Cows

    P3047 [USACO12FEB]附近的牛Nearby Cows 题目描述 Farmer John has noticed that his cows often move between near ...

  3. P3047 [USACO12FEB]附近的牛Nearby Cows

    https://www.luogu.org/problemnew/show/P304 1 #include <bits/stdc++.h> 2 #define up(i,l,r) for( ...

  4. luogu 3047 [USACO12FEB]附近的牛Nearby Cows 树形dp

    $k$ 十分小,直接暴力维护 $1$~$k$ 的答案即可. 然后需要用父亲转移到儿子的方式转移一下. Code: #include <bits/stdc++.h> #define M 23 ...

  5. LuoguP3047 [USACO12FEB]附近的牛Nearby Cows(树形DP,容斥)

    \[f[u][step] = \begin{cases} C[u] & step = 0 \\ (\sum{f[v][step - 1]}) - f[u][step - 2] \cdot (d ...

  6. 树形DP【洛谷P3047】 [USACO12FEB]附近的牛Nearby Cows

    P3047 [USACO12FEB]附近的牛Nearby Cows 农民约翰已经注意到他的奶牛经常在附近的田野之间移动.考虑到这一点,他想在每一块土地上种上足够的草,不仅是为了最初在这片土地上的奶牛, ...

  7. 【洛谷3047】[USACO12FEB]附近的牛Nearby Cows

    题面 题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into acc ...

  8. [USACO12FEB]附近的牛Nearby Cows

    题目描述 Farmer John has noticed that his cows often move between nearby fields. Taking this into accoun ...

  9. 【[USACO12FEB]附近的牛Nearby Cows】

    我记得我调这道题时中耳炎,发烧,于是在学长的指导下过了也没有发题解 发现我自己的思路蛮鬼畜的 常规操作:\(f[i][j]\) 表示到\(i\)的距离为\(j\)的奶牛有多少只,但注意这只是在第二遍d ...

随机推荐

  1. 使用TK框架中selectByPrimaryKey

    使用TK框架中selectByPrimaryKey(Object key),需要注意要在entity里注明哪个字段是主键,否则会不知道哪个是PrimaryKey会随机一个字段就报错. 如下: 引入 i ...

  2. 手把手教你看MySQL官方文档

    前言: 在学习和使用MySQL的过程中,难免会遇到各种问题.不知道当你遇到相关问题时会怎么做,我在工作或写文章的过程中,遇到不懂或需要求证的问题时通常会去查阅官方文档.慢慢的,阅读文档也有了一些经验, ...

  3. 巧用SQL拼接语句

    前言: 在日常数据库运维过程中,可能经常会用到各种拼接语句,巧用拼接SQL可以让我们的工作方便很多,达到事半功倍的效果.本篇文章将会分享几个日常会用到的SQL拼接案例,类似的SQL还可以举一反三,探索 ...

  4. Jenkins 基础篇 - 基础设置

    站点设置 刚搭建好 Jenkins 环境,你还需要做一些简单设置,让我们的 Jenkins 看起来是这么一回事,特别是你要用于生产环境的时候.首先就是域名配置,如果你为 Jenkins 服务分配了一个 ...

  5. ALPHA任务拆解

    项目 内容 这个作业属于哪个课程 BUAA2020软件工程 这个作业的要求在哪里 作业要求 我们在这个课程的目标是 学会团队合作,共同开发一个完整的项目 这个作业在哪个具体方面帮助我们实现目标 团队任 ...

  6. golang:运算符总结

    算术运算符 运算符 示例 结果 + 10 + 5 15 - 10 - 5 5 * (除数不能为0) 10 * 5 50 / 10 / 5 2 % (除数不能为0) 10 % 3 1 ++ a = 0; ...

  7. SecureCRT配置自动记录日志

    很多人用SecureCRT时,希望自动记录日志,一个是方便以后查阅,一个是对自己的操作有个记录.可以看看自己做了什么操作,有时甚至可以看看之前是不是犯了什么错,是个很不错的功能. 设置很简单,还可以根 ...

  8. spring MyBatis的相关面试题

    (相关面试题! 供参考!) 1.ORM框架有哪些? MyBatis:半自动化框架(不是纯ORM) 需要写动态SQL语句,实体类和SQL语句之间建立映射关系 Spring:轻量级框架, Java EE的 ...

  9. .Net Core with 微服务 - Ocelot 网关

    上一次我们通过一张架构图(.Net Core with 微服务 - 架构图)来讲述了微服务的结构,分层等内容.从现在开始我们开始慢慢搭建一个最简单的微服务架构.这次我们先用几个简单的 web api ...

  10. python批量向kafka塞数据

    python批量向kafka塞数据 from kafka import KafkaClient from kafka.producer import SimpleProducer from kafka ...