【CF580C】Kefa and Park
题目大意:给定一棵 N 个节点的有根树(其中根节点始终为 1 号节点),点有点权,点权只有 1 和 0 两种,求从根节点到叶子节点的路径中,有多少条路径满足:路径上最大连续点权为 1 的节点个数不超过 M。
题解:一开始想到了树形dp,即:\(dp[i][0/1]\) 表示从根节点到该点的路径中不选/选该点的最大连续 1 的个数,则状态的转移涉及到该节点的 \(val\) 值和其父节点的 \(val\) 值。不过,其实没有必要记录下每一个节点的状态,原因是:如果到当前节点的连续 1 的个数已经超过了限制,那么后面无论怎样,这条路径都对答案没有贡献。因此,可以直接记录下到当前节点连续的长度,超过限制直接剪枝,由剪枝操作还可以知道,若当前节点的权值是 0,无论前面的值是多少,都对后面的值没有任何影响。
另外:建树的时候应该添加双向边,因为题目数据中给的关系并不是严格的父子关系。
树形 dp 代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
struct node{
int nxt,to;
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to){
e[++tot]=node{head[from],to},head[from]=tot;
}
int n,m,ans,val[maxn],dp[maxn][2];
void read_and_parse(){
n=read(),m=read();
for(int i=1;i<=n;i++)val[i]=read();
for(int i=1;i<n;i++){
int from=read(),to=read();
add_edge(from,to),add_edge(to,from);
}
}
void dfs(int u,int fa){
if(!val[u])dp[u][0]=max(dp[fa][0],dp[fa][1]);
else if(!val[fa])dp[u][1]=1,dp[u][0]=dp[fa][0];
else dp[u][1]=dp[fa][1]+1,dp[u][0]=max(dp[fa][1],dp[fa][0]);
int ok=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(v==fa)continue;
ok=0,dfs(v,u);
}
if(ok&&max(dp[u][0],dp[u][1])<=m)++ans;
}
void solve(){
dfs(1,0);
printf("%d\n",ans);
}
int main(){
read_and_parse();
solve();
return 0;
}
优化后代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
struct node{
int nxt,to;
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to){
e[++tot]=node{head[from],to},head[from]=tot;
}
int n,m,ans,val[maxn];
void read_and_parse(){
n=read(),m=read();
for(int i=1;i<=n;i++)val[i]=read();
for(int i=1;i<n;i++){
int from=read(),to=read();
add_edge(from,to),add_edge(to,from);
}
}
void dfs(int u,int fa,int cnt){
if(cnt>m)return;
bool flag=1;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;if(v==fa)continue;
flag=0;
if(val[v])dfs(v,u,cnt+1);
else dfs(v,u,0);
}
ans+=flag;
}
void solve(){
dfs(1,0,val[1]);
printf("%d\n",ans);
}
int main(){
read_and_parse();
solve();
return 0;
}
【CF580C】Kefa and Park的更多相关文章
- 线段树+哈希【CF580E】Kefa and Watch
线段树+哈希[CF580E]Kefa and Watch Description \(n\)个数的字符串,\(m + k\)个操作 1 l r k把\(l - r\)赋值为\(k\) 2 l r d询 ...
- UOJ58 【WC2013】糖果公园
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 【Henu ACM Round#14 E】Kefa and Watch
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 在做之前需要了解一个知识点. 就是如果一个字符串s是一个a循环串. (字符串的长度设为n,下标从1开始 那么s[1..n-a]和s[ ...
- 【Henu ACM Round#14 D】Kefa and Dishes
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 状态压缩动规. 可以写成记忆化搜索的形式. f[bit][p] 表示选取的菜的情况为bit(用0..2^(N)-1的二进制形式表示各 ...
- 【数据库】_由2000W多条开房数据引发的思考、实践----给在校生的一个真实【练耙场】,同学们,来开始一次伟大的尝试吧。
× 缘起---闲逛博客园 前几天的时候,在某一QQ群看到一条消息“XXX酒店开房XXXBTXX迅雷BT下载”,当时是一目十行的心态浏览,目光掠过时, 第一反应我想多了~以为是XX种子(你懂的~ ...
- 【转载】Storm TickTuple 意外停止
原文链接转自:http://woodding2008.iteye.com/blog/2328114 Storm的滑动窗口TickTuple通常用来控制bolt定制执行入库操作,使用过程中遇到了Tick ...
- 【转】Python之正则表达式(re模块)
[转]Python之正则表达式(re模块) 本节内容 re模块介绍 使用re模块的步骤 re模块简单应用示例 关于匹配对象的说明 说说正则表达式字符串前的r前缀 re模块综合应用实例 参考文档 提示: ...
- 【1】【JUC】JDK1.8源码分析之ReentrantLock
概要: ReentrantLock类内部总共存在Sync.NonfairSync.FairSync三个类,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQ ...
- 【BZOJ2310】ParkII 插头DP
[BZOJ2310]ParkII Description Hnoi2007-Day1有一道题目 Park:给你一个 m * n 的矩阵,每个矩阵内有个权值V(i,j) (可能为负数),要求找一条回路, ...
随机推荐
- PX Deq: Execution Msg 等待事件
可参考 MOS文档: WAITEVENT: "PX Deq Credit: send blkd" (Doc ID 271767.1) P1 = sleeptime/senderid ...
- flask前端与后端之间传递的两种数据格式:json与FormData
json格式 双向! 前端 ==>后端:json格式 后端 ==>前端:json格式 html <!-- html部分 --> <form enctype='applic ...
- Ubuntu16.04上用源代码安装ICE
ubuntu16.04上用源代码安装ICE
- SSIS 遍历目录,把文件内容导入数据库
最近接手一个项目,程序的基本框架是:程序A导出数据,以.tsv格式存储,数据列之间以tab间隔:程序B吃文档,把数据导入到数据库中,并把处理过的文档备份/移动到指定的目录中.为了快速开发,程序B设计成 ...
- jqGrid 列内容超过一定长度省略表示
jqgrid初始化方法中的,对应列添加formatter方法 colNames : [ "描述" ], colModel : [ { name : 'description', i ...
- C# 基于泛型的自定义线性节点链表集合示例
本例子实现了如何自定义线性节点集合,具体代码如下: using System; using System.Collections; using System.Collections.Generic; ...
- android studio 下载 sdk 失败
android studio 打开项目出现以下错误时,点击去安装,会提示"All packages are not available for download" 错误. 解决办法 ...
- SpringBoot日记——缓存的使用
SpringBoot核心技术的东西基本上都有介绍过了,接下来,进阶点~来说说缓存吧~ 缓存这个词不少同学应该不会很陌生.而我们这里主要使用的就是Redis. 客户端第一次请求的时候是从库里拿出我们需要 ...
- 移动端三合一瀑布流插件(原生JS)
没有前言,先上DEMO(手机上看效果更佳)和 原码. 瀑布流形式的图片布局方式在手机等移动端设备上运用广泛,比较常见的是下面前两种: 一.等宽等高 这种形式实现起来非常容易,这里就不再多说. 二.等宽 ...
- C#_委托
委托属于C#中的新名词,它的应用也非常广泛,例如事件就是委托最简单而又直接的例子. 那么首先说说什么是委托,其实委托在用过C或者C++的人看来就是函数指针,不过使用C#的大多数人都没有用过这两门语言, ...