[AGC008F] Black Radius(树形dp)
神题啊!!
Description
给你一棵有N个节点的树,节点编号为1到N,所有边的长度都为1
"全"对某些节点情有独钟,这些他喜欢的节点的信息会以一个长度为N的字符串s的形式给到你,具体一点就是对于1<=i<=N,si=1表示"全"喜欢节点i,为0表示"全"不喜欢节点i
一开始的时候,所有的节点都是白色的,"全"会进行以下操作恰好一次:
选择一个他喜欢的节点v和一个非负整数d,然后将所有与节点v距离不超过d的节点全部涂黑
问进行操作之后,有多少种不同的涂色情况?两种情况不同当且仅当两种情况存在一个节点i的颜色不同
Input
第一行一个正整数N
接下来N−1行每行两个正整数xi,yi表示xi到yi有一条边
最后一行一个字符串s
Output
输出不同染色情况的数量
题解:
设\(f(i,d)\),为把距 \(i\) 点小于等于 \(d\) 染成黑色的集合。
不过这样染色的时候会有重复的方案,我们考虑下何时会重复。
当 $f(i,d_1) $ 和 \(f(j,d2)\),重复时,当且仅当 \(i\),\(j\) 之间存在一点 \(k\),使得 \(f(k,d1-dist(i,k))\),\(dist(i,j)\) 表示 \(i\),\(j\) 的树上距离。
这个很显然吧……
所以对于某个\(f(i,d)\),如果有\(f(k,d1-dist(i,k))=f(i,d)\),那么 \(f(i,d)\) 就会被重复算。
对于每一个\(i\),我们只用考虑更他相邻的点和他的重复情况就可以了。(也很显然吧)
那我们再考虑一下,何时 \(f(i,d)=f(k,d-1)\)。
还是很显然,如果以 \(k\) 为根,\(i\) 的子树全部被染成黑色的话,他们就相等。
所以可以得知,\(d\) 的上界为 \(i\) 到他子树中的最远点的距离。
那我们用树形dp,\(O(n)\) 算出,然后暴力枚举每个 \(i\),算 \(d\) 的上界。
那下界呢? 如果 \(i\) 点是特殊点,无疑是0,那如果不是呢?
如果不是,那么若存在一个特殊节点j满足方案\((i,d)\)中 \(j\) 所在子树内所有节点均被染成黑色,\((i,d)\) 就是一个合法的染色方案。故我们只需要求出从 \(i\) 出发的至少经过 1 个特殊节点到达 \(j\) 子树中的最远节点的距离的最小值,就是可行的 \(d\) 的最小值。
知道每个 \(i\),\(d\) 的上下界,那就算吧!
CODE:
#include<iostream>
#include<cstdio>
using namespace std;
int d1[200005],d2[200005];
int d3[200005],d4[200005];
//d1:子树中的最远距离
//d2:非子树中的最远距离
//d3:这个节点到子树中至少经过1个特殊节点到达子树中的最远节点最小距离
//d4:从他父亲出发,不经过这棵子树的最远路径
int n,x,y,siz[200005],col[200005],fa[200005];
long long ans=0;
int tot=0,h[200005];
struct Edge{
int x,next;
}e[400005];
char ch[200005];
inline void add_edge(int x,int y){
e[++tot].x=y;
e[tot].next=h[x],h[x]=tot;
}
void dfs1(int x,int father){
siz[x]=col[x],fa[x]=father;
d3[x]=col[x]?0:1e9;
for(int i=h[x];i;i=e[i].next){
if(e[i].x==father)continue;
dfs1(e[i].x,x);
siz[x]+=siz[e[i].x];
d1[x]=max(d1[x],d1[e[i].x]+1);
if(siz[e[i].x])
d3[x]=min(d3[x],d1[e[i].x]+1);
}
}
void dfs2(int x,int father){
if(father)d4[x]=d2[x]-1;
int maxn=0,sec=0;
for(int i=h[x];i;i=e[i].next){
if(e[i].x==father)continue;
if(d1[e[i].x]+1>maxn)
sec=maxn,maxn=d1[e[i].x]+1;
else sec=max(sec,d1[e[i].x]+1);
}
for(int i=h[x];i;i=e[i].next){
if(e[i].x==father)continue;
if(d1[e[i].x]+1==maxn)
d2[e[i].x]=max(d2[x],sec)+1;
else d2[e[i].x]=max(d2[x],maxn)+1;
dfs2(e[i].x,x);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
scanf("%s",ch+1);
for(int i=1;ch[i];i++)
col[i]=ch[i]-'0';
dfs1(1,0),dfs2(1,0);
for(int i=1;i<=n;i++){
int minv,maxv;
minv=min(d3[i],siz[1]==siz[i]?(int)1e9:d2[i]);
maxv=max(d1[i],d2[i])-1;
for(int j=h[i];j;j=e[j].next){
if(e[j].x==fa[i])maxv=min(maxv,d1[i]+1);
else maxv=min(maxv,d4[e[j].x]+1);
}
if(maxv>=minv)ans+=1LL*maxv-minv+1;
}
printf("%lld",ans+1);
}
[AGC008F] Black Radius(树形dp)的更多相关文章
- [agc008f] Black Radius 树形dp
Description 给你一棵有NN个节点的树,节点编号为11到NN,所有边的长度都为11 "全"对某些节点情有独钟,这些他喜欢的节点的信息会以一个长度为NN的字符串ss ...
- [Agc008F]Black Radius
[AGC008F] Black Radius Description 给你一棵有N个节点的树,节点编号为1到N,所有边的长度都为1 "全"对某些节点情有独钟,这些他喜欢的节点的信息 ...
- 2017国家集训队作业[agc008f]Black Radius
2017国家集训队作业[agc008f]Black Radius 时隔4个月,经历了省赛打酱油和中考各种被吊打后,我终于回想起了我博客园的密码= = 题意: 给你一棵树,树上有若干个关键点.选中某 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
随机推荐
- C盘扩展卷是灰色的扩容方法
当想要扩容C盘的时候可能会发现C盘的扩展卷竟然是灰色的.原因是C盘旁边没有紧挨着的“”未分配空间“”, 只要将D盘的空间分出一些来就可以了. !!!磁盘的分区合并有风险,重要文件等记得先备份 !!! ...
- Spring Cloud学习介绍
最近在学spring cloud, 整理了下 简单知识要求: 1.要了解springboot 2.了解分布式架构 3.了解微服务 4.了解springcloud是做什么的 带着这些,初学者 就至少有个 ...
- neo4j 安装
查看 http://ip:7474/browser/
- 第三篇:彻底解决ssh.invoke_shell() 返回的中文问题
接上一篇,前两篇解决中文的问题主要是在字符集上做的手脚,即将中文转成英文,但是有一种情况我们都来不及做转换,即登录时服务器直接返回了中文内容: 此时程序报了如下错误,其实还是字符集问题: 为此:我们可 ...
- PHP消息队列学习
在我们平常网站设计时,会遇到“给用户群发短信”,“商城订单系统大批量订单处理”,“商城秒杀活动”等需求,这些功能,都有一个共同的特点:就是在面对高迸发的同时,必须要保证系统处理数据的有效性.那么如何处 ...
- 适合学习的QT开源项目-SerialTool
https://github.com/Skiars/SerialTool A cross platform Serial-Port/TCP/UDP debugging tool. SerialTool ...
- 使用virtualbox安装的Ubuntu,窗口分辨率过小,使用增强工具完成和vmtools一样的功能。
今天用VirtualBox成功装上Ubuntu10.04之后发现了一个问题:默认情况下 ubuntu 的分辨率最高只能设到800*600.但是对于自己的大显示器,在分辨率800*600的ubuntu窗 ...
- Qt中修改QtoolTip的样式
Qt中的QtoolTip有几个需要注意的: 1.不能直在堆或栈中生成QToolTip对象.因为其构造函数为私有.2.从widget获取的tooltip不是tooltip对象,而是tooltip中的文本 ...
- poj-3253 fence repair(贪心题)
题目描述: Farmer John wants to repair a small length of the fence around the pasture. He measures the fe ...
- 2015-2016 Northwestern European Regional Contest (NWERC 2015)
训练时间:2019-04-05 一场读错三个题,队友恨不得手刃了我这个坑B. A I J 简单,不写了. C - Cleaning Pipes (Gym - 101485C) 对于有公共点的管道建边, ...