《算法竞赛·快冲300题》每日一题:“附近的牛”

news2025/2/28 21:26:49

算法竞赛·快冲300题》将于2024年出版,是《算法竞赛》的辅助练习册。
所有题目放在自建的OJ New Online Judge。
用C/C++、Java、Python三种语言给出代码,以中低档题为主,适合入门、进阶。

文章目录

  • 题目描述
  • 题解
  • C++代码
  • Java代码
  • Python代码

附近的牛” ,链接: http://oj.ecustacm.cn/problem.php?id=1897

题目描述

【题目描述】 农场由 N 个点和 N-1 条双向路径组成。通过 N-1 条路径使得所有点连通。
点 i 有 C(i) 头奶牛,奶牛有时会穿过 K 条路径移动到不同的点。
农夫想要在每个点 i 种植足够的草来喂养最大数量的奶牛 M(i)。
也就是说,对于每个点 i ,农夫需要考虑最多可能会有多少头奶牛到达该点 i 。
请求出每个 M(i)。
【输入格式】 第 1 行:两个整数, N 和 K,1 <= N <= 100,000,1 <= K <= 20。
第 2 行 - 第 N 行:两个整数 u 和 v ,表示点 u 和点 v 之间存在路径,1 <= u, v <= N。
第 N + 1 行 - 第 2N 行:第 N + i 行输入 1 个整数表示 C(i),0 <= C(i) <= 1000。
【输出格式】 输出 N 行,第 i 行输出 M(i)。
【输入样例】

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

【输出样例】

15
21
16
10
8
11

题解

   简单概况题意:一棵有n个点、n-1条边的树,每个点有权值,对每个节点求出距离它不超过k的所有节点权值之和m。
   先考虑暴力法。对任意一个点i,直接遍历距离它不超过k的所有点,求它的权值之和mi。编码用dfs,从每个点dfs,深度为k时返回。计算量有多大?假设这棵树是一棵满二叉树,从一个点出发走k步,可能走到 2 k 2^k 2k个点,当k=20时, 2 20 > 100000 2^{20}>100000 220>100000,已经包括了所有的n个点。所以单独求一个点的m是O(n)的,求n个点的m是 O ( n 2 ) O(n^2) O(n2)的,超时。
   如何优化?对每个点单独计算m,导致了大量的重复计算。例如相邻的两个点u、v,点u的距离k之内的点,和点v的距离k之内的点,绝大部分是重复的,只需要计算那些不同的点即可。
   所以本题的思路和编码步骤是:(1)首先计算以任意点i为根的子树的权值之和si,做一次DFS即可;(2)再计算从任意点i出发的权值之和mi,它包括了i的子树权值之和si,以及i的父节点方向的权值,这个计算利用了前面的结果。
   (1)计算任意点i的子树的权值之和。
   设状态为dp[][],dp[i][j]表示以第i个节点为根的子树上,从i走j步到达的子节点的权值之和。注意不是从i出发的距离j步之内的权值之和,而是距离为j步的那些子节点的权值之和。代码用dfs1()函数做一次DFS,即可计算出每个点的dp[][]。
   注意,dp[][]在以下的计算中有新的含义:dp[i][j]表示从i出发,走j步到达的节点的权值之和。不仅仅包括i的子树上的第j步节点,而且包括父节点方向的第j步的节点。
   (2)计算点v的距离k内的所有节点权值之和m,见下图。
在这里插入图片描述

   包括两部分:
   1)v向下走的子树上的节点,这部分权值等于之前在dfs1()算出的dp[v][j],0≤j≤k。
   2)v向上走的距离k内的节点,这部分权值之和怎么算?v往上走一步是父节点u,u对应的dp[u][j-1],是u的距离第k-1步的那些节点的权值之和,它包括图中虚线(1)、(2)、(3)的箭头终点上的几个节点权值之和。计算v在u方向的权值之和时,应该加上(2)、(3),不要加(1),也就是从dp[u][j-1]中去掉dp[v][j-2],即dp[u][j-1] - dp[v][j-2]。
   代码dfs2()函数中,用tot[]记录答案,tot[u]是第u点的距离k内的权值之和。dfs2()中的dp[u][i]已经更新为新含义,第20行累加dp[u][i],0≤j≤k,即可计算出tot[u]。
   第21-26行计算并更新dp[][]为新含义下的权值之和。注意不要忘记更新dp[v][1],在第24行加上v的父节点u的权值dp[u][0]。
   dfs2()有两个关键。
   1)第23行j从k到2,倒过来循环。dp[v][j] += dp[u][j - 1] - dp[v][j - 2],左边的dp[][]是新含义,右边的dp[][]是dfs1()计算时的旧含义,j倒过来循环能避免破坏这个关系。
   2)第25行在最后继续dfs2(),也就是在前面更新dp[][]之后再继续DFS。首次进入dfs2()时,u是整棵树的根节点1,它没有父节点,计算tot[1]直接累加dp[u][i]即可。后面继续计算子节点的tot[]时,需要按上图的说明,计算两个部分的权值。
   dfs1()和dfs1()的计算复杂度都是O(n)。

【重点】 树形DP 。

C++代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
const int K = 22;
int n, k;
int c[N];
vector<int> e[N];                   //存图
int dp[N][K];
void dfs1(int u, int fa) {          //dp[i][j]:i往子树走j步,第j步子节点权值之和
    dp[u][0] = c[u];                //先加上自己的权值
    for(auto v : e[u]){
        if(v == fa) continue;
        dfs1(v, u);                 //注意:先dfs,计算出子节点的dp[][],回溯后带回
        for(int j=1; j<=k; j++)     //从第j=1步开始,一步一步往下走并计算
            dp[u][j] += dp[v][j - 1];
    }
}
int tot[N];
void dfs2(int u, int fa) {
    for(int i=0; i<=k; i++)  tot[u] += dp[u][i]; //第 1)部分:先累加u子树上,k步内的权值之和        
    for(auto v : e[u]){                          //第 2)部分:然后计算u的子节点的权值之和
        if(v == fa) continue;
        for(int j=k; j>=2; j--)  dp[v][j] += dp[u][j - 1] - dp[v][j - 2];
        dp[v][1] += dp[u][0];                    //v往父节点u走一步,加上u的权值
        dfs2(v, u);
    }
}
int main(){
    cin>>n>>k;
    for(int i=1; i<n; i++) {
        int u, v; scanf("%d%d", &u, &v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    for(int i=1; i<=n; i++)  scanf("%d", &c[i]);
    dfs1(1, 1);     //以1为根,求每个点往子节点方向走k步的m值
    dfs2(1, 1);     //仍然从根1出发,求每个点的权值之和
    for(int i=1; i<=n; i++)  printf("%d\n", tot[i]);
    return 0;
}

Java代码

 

Python代码

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/990058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习笔记——Java入门第三季

1.1 Java异常简介 异常&#xff1a;有异于常态&#xff0c;和正常情况不一样&#xff0c;有错误出现&#xff0c;阻止当前方法或作用域。 异常处理&#xff1a;将出现的异常提示给编程人员与用户&#xff0c;使原本将要中断的程序继续运行或者退出。并且能够保存数据和释放资源…

独家!网络机顶盒什么牌子好?热门网络电视机顶盒排名TOP5

电视机搭配网络机顶盒看剧是很多人的消遣方式&#xff0c;不过在挑选网络机顶盒时很多人踩过雷&#xff0c;像卡顿、死机、广告多等问题频发&#xff0c;近来很多人咨询我网络机顶盒什么牌子好&#xff0c;我以销量为基础盘点了网络电视机顶盒排名&#xff0c;哪些品牌最受欢迎…

OpenResume简历解析官方技术文档(翻译)

OpenResume简历解析官方技术文档(翻译) 本文是对OpenResume建立解析器官方技术文档《Resume Parser Playground》的翻译。 相关连接&#xff1a; OpenResume官网 OpenResume简历解析器的官方地址 OpenResume的Github 简历解析测试环境 该测试环境展示了 OpenResume 简历…

新型人工智能技术让机器人的识别能力大幅提升

原创 | 文 BFT机器人 在德克萨斯大学达拉斯分校的智能机器人和视觉实验室里&#xff0c;一个机器人在桌子上移动一包黄油玩具。通过达拉斯分校计算机科学家团队开发的新系统&#xff0c;机器人每推动一次&#xff0c;就能学会识别物体。 新系统允许机器人多次推动物体&#xf…

后端/DFT/ATPG/PCB/SignOff设计常用工具/操作/流程及一些文件类型

目录 1.PD/DFT常用工具及流程 1.1 FC和ICC2 1.2 LC (Library compiler) 1.3 PrimeTime 1.4 Redhawk与PA 1.5 Calibre和物理验证PV 1.6 芯片设计流程 2.后端、DFT、ATPG的一些常见文件 2.1 LEF和DEF 2.2 ATPG的CTL和STIL 2.3 BSDL 2.4 IPXCT 3.PCB设计的一些工作和工…

宏定义天坑记录

宏定义天坑记录 事件原委与推理过程 在编译一个使用了Protobuf的项目时出现了如下报错 [ybVM-8-7-centos boost_searcher]$ make g -o http_server http_server.cc data/raw_html.pb.cc -stdc11 -lboost_system -lboost_filesystem -lpthread -ljsoncpp -lprotobuf In file…

JAVA学习-IDEA创建父子项目

JAVA培训-创建父子项目 一、创建父模块 1、new一个新项目&#xff0c;如下图所示&#xff1a; 2、由于这里是父级Maven项目&#xff0c;所以什么都不用选&#xff0c;只需要将SpringBoot版本选成稳定的版本即可。后面带&#xff08;SNAPSHOT&#xff09;&#xff0c;代表版本…

如何理解focal loss/GIOU(yolo改进损失函数)

Focal Loss的公式如下&#xff1a; Focal Loss -α(1 - p)^γ * log 其中&#xff0c;α是正样本的调节因子&#xff0c;γ是控制难易样本权重分配的参数&#xff0c;p是模型预测的概率值。 根据公式&#xff0c;可以看出当样本属于困难样本时&#xff0c;(1 - p) 的值较大…

如何全方位了解购房信息?VR全景技术为您解答

在存量房贷利率下调政策下&#xff0c;房子逐渐回归到居住属性&#xff0c;在对于有购房刚需的客户来说&#xff0c;无疑是一大利好政策&#xff0c;此类客户有着强烈的看房购房需求&#xff0c;那么该如何全方位的了解购房信息呢&#xff1f; 房企通过VR全景展示、3D样板房、V…

论文阅读 (100):Simple Black-box Adversarial Attacks (2019ICML)

文章目录 1 概述1.1 要点1.2 代码1.3 引用 2 背景2.1 目标与非目标攻击2.2 最小化损失2.3 白盒威胁模型2.4 黑盒威胁模型 3 简单黑盒攻击3.1 算法3.2 Cartesian基3.3 离散余弦基3.4 一般基3.5 学习率 ϵ \epsilon ϵ3.6 预算 1 概述 1.1 要点 题目&#xff1a;简单黑盒对抗攻…

Vue中的图标

Vue中的图标 https://iconpark.oceanengine.com/official 官方教程&#xff1a;icon-park/vue - npm 1.IconPark 2.基本使用 下载 yarn add icon-park/vue --save 启动 yarn run serve 项目中引用 <script> import { TableFile } from icon-park/vue; export defa…

微信小程序遇到的一些问题及解决方法(设备安装)

微信小程序遇到的一些问题及解决方法 1、[js将字符串按照换行符分隔成数组](https://blog.csdn.net/pgzero/article/details/108730175)2、[vue byte数组](https://www.yzktw.com.cn/post/1202765.html)3、使用vant-weapp的文件上传capture"camera" 无法直接调用摄像…

渗透数据工程师

什么是渗透测试 渗透测试就是模拟真实黑客的攻击手法对目标网站或主机进行全面的安全评估&#xff0c;与黑客攻击不一样的是&#xff0c;渗透测试的目的是尽可能多地发现安全漏洞&#xff0c;而真实黑客攻击只要发现一处入侵点即可以进入目标系统。 一名优秀的渗透测试工程师也…

Web应用测试 —— Cookie,Session和Token

Cookie&#xff0c;Session 和 Token都是 Web 应用中常用的技术&#xff0c;它们在用户认证和状态管理中发挥了重要作用。下面是它们的基本定义和区别&#xff1a;Cookie Cookie 是服务器发送到用户浏览器并保存在浏览器上的一小块数据&#xff0c;它会在浏览器向同一服务器再次…

关于 Unity 连接 MuMu 模拟器上的 Unity Remote 5 的方法

在使用 Unity 开发 Android 的过程中&#xff0c;可以通过使用 Unity Remote 这个 app 来和真机连接&#xff0c;进而在真实环境下进行测试性能等工作&#xff0c;而本次则是由于其他问题引出的一个小坑&#xff0c;记录以备后续查询。 这次是由于在自学过程中遇到的一个工程&…

VM+Ubuntu+Xshell+Xftp安装教程

目录 VM17安装教程 检查网络连接 Ubuntu环境搭建 UBUNTU 系统配置 1、 SSH 服务器配置 服务端&#xff08;必须&#xff09; 1.安装 ssh 服务端 2.确认 sshserver 是否启动了&#xff08;看见 sshd 说明已启动&#xff09; 3.启动 sshserver 4.SSH 配置&#xff08;如果…

【Python】环境的搭建

前言 要想能够进行 Python 开发, 就需要搭建好 Python 的环境. 需要安装的环境主要是两个部分: 运行环境: Python开发环境: PyCharm 一、安装 Python 1.找到官方网站 官网&#xff1a;Welcome to Python.org 2.找到下载页面 点击download中的Windows 3.选择稳定版中的Win…

Vue+Element Progress 进度条显示文字 %修改,使用format方法显示文字可自定义

需求 要实现这样子的 将进度条里显示的文字 后的 %去掉 主要用到 format 方法 代码 <el-progress :text-inside"true" :stroke-width"30" :format"format":percentage"usageA"></el-progress>methods: {format(percent…

南大通用数据库-Gbase-8a-报错集锦-06-Stack Overflow

目录 一、数据库版本信息 二、报错信息 三、报错SQL 四、解决方法 1、修改参数thread_stack 2、改写SQL &#xff08;1&#xff09;改为内连接 &#xff08;2&#xff09;临时表 一、数据库版本信息 二、报错信息 三、报错SQL SQL包含2000多个or条件。 四、解决方法 1、…

MySQL——连接查询

2023.9.4 连接查询相关sql92语句笔记&#xff1a; #连接查询。 又称多表查询&#xff0c;当查询的字段来自多个表时&#xff0c;就会用到连接查询。 #等值连接 /* ①多表等值连接的结果为多表的交集部分 ②n表连接&#xff0c;至少需要n-1个连接条件 ③多表的顺序没有要求 ④一…