[bzoj4472][树形DP] Salesman
题目
解说
刚看完这道题感觉还是挺乱的,可能那时候脑子不太清醒,一度觉得自己又要重拾Tarjan了。当然最后还是发觉应该用树形DP。
(以下dp[u]代表以u为根的包括自己在内的子树的最大利润,bool g[u]表示u及其子树的方案数是否唯一,唯一则为0,否则为1,t[u]代表u的次数,v[u]代表u的价值)
计算最大利润确实挺简单。有点像之前做过的空调教室,但是多了次数限制和负数,但这不难处理。计算u的时候因为每个儿子在走完之后必须返回u来回到根节点,因此我们只能对儿子的dp值进行排序,选取前t[u]-1个,并且遇到负数立即停止因为接下来选的负数只能使总价值变小。
那么怎么处理方案是否唯一呢?
我们开一个bool数组g表示u及其子树的方案数是否唯一。显然,只有以下3种情况下方案数不唯一:
某个取得的儿子dp值为0(选不选都可以)
某个取得的儿子g值为1(在这颗子树中有不同的路径)
下个未选的儿子和最后选择的儿子f值相同(可以替换)(我写的时候忽略了这一点但是还是A了,大约是数据太弱了)
那么就从根开始递归一遍就可以了哦,最后看dp[1]和g[1]就可以了。
(部分实在想不上来的做法参考了DZN大佬的,谢谢啦~)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=+,Inf=;
inline int read(){
int s=,w=;
char ch=getchar();
while(ch<''||ch>''){if(ch=='-')w=-;ch=getchar();}
while(ch>=''&&ch<='') s=s*+ch-'',ch=getchar();
return s*w;
}
int n,head[maxn],tot,v[maxn],t[maxn],dp[maxn];
bool g[maxn];
struct node{
int to,next;
}e[*maxn];
void Add(int a,int b){
e[tot].to=b;
e[tot].next=head[a];
head[a]=tot;
tot++;
}
void dfs(int x,int fa){
priority_queue<pair<int,int> > q;//按照dp值大小排序
for(int i=head[x];i;i=e[i].next){
int v=e[i].to;
if(v==fa) continue;
dfs(v,x);
q.push(make_pair(dp[v],v));
}
int num=,sum=,judge=;
while(!q.empty()&&num<t[x]-){
if(q.top().first<) break;//出现拖后腿的立即停止
if(q.top().first==){//有0说明方案不为1,
//且0后面要么是0要么是负的,都无法做贡献,直接退
judge=;
break;
}
sum+=q.top().first;
if(g[q.top().second]==) judge=;
q.pop();
num++;
}
dp[x]=sum+v[x];
g[x]=judge;
}
int main(){
tot=;
t[]=Inf;//注意自己家可以走无数次
n=read();
for(int i=;i<=n;i++) v[i]=read();
for(int i=;i<=n;i++) t[i]=read();
for(int i=;i<=n-;i++){
int x,y;
x=read(); y=read();
Add(x,y);
Add(y,x);
}
dfs(,);
printf("%d\n",dp[]);
if(g[]) printf("solution is not unique");
else printf("solution is unique");
return ;
}
幸甚至哉,歌以咏志。
[bzoj4472][树形DP] Salesman的更多相关文章
- 【BZOJ4472】salesman(树形DP)
题意: 给定一颗有点权的树,每个树上的节点最多能走到lim[u]次,求一条路径,使路径上的点权和最大,每个节点上的点权如果走了多次只能算一次.还要求方案是否唯一. 思路:每个点只能取lim[u]-1个 ...
- bzoj4472: [Jsoi2015]salesman(树形dp)
Description 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收益.这些净收益可 ...
- 【树形DP】JSOI BZOJ4472 salesman
题目内容 vjudge链接 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇 之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收 益.这些 ...
- BZOJ 4472 [Jsoi2015]salesman(树形DP)
4472: [Jsoi2015]salesman Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 417 Solved: 192[Submit][St ...
- 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 ...
随机推荐
- C语言入门理解指针
本文章为本人原创,适合于刚入坑C语言,对于指针的定义和用法模糊不清的同学,如有不正,请各位指出. 从根本来说,指针变量也是变量,只是int变成了int *,以此类推.只不过指针变量里面放的内容是普通变 ...
- 用ABAP 生成二维码 QR Code
除了使用我的这篇blogStep by step to create QRCode in ABAP Webdynpro提到的使用ABAP webdynpro生成二维码之外,也可以通过使用二维码在线生成 ...
- Immer.js简析
开始 在函数式编程中,Immutable这个特性是相当重要的,但是在Javascript中很明显是没办法从语言层面提供支持,但是还有其他库(例如:Immutable.js)可以提供给开发者用上这样的特 ...
- 大数据篇:ElasticSearch
ElasticSearch ElasticSearch是什么 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口. ...
- django models中的class meta
Django models中的meta选项 通过一个内嵌类 "class Meta" 给你的 model 定义元数据, 类似下面这样: class Foo(models.Model ...
- 03、MySql的数据类型
MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 1.数字类型 类型 大小 范围(有符号) 范围(无符号) ...
- vue组件通信(props,$emit,$attrs,$listeners)
朝颜陌 vue基础----组件通信(props,$emit,$attrs,$listeners) 一.父传子,子传孙 1. props 1>在父组件中通过子组件自定义的标签属性来传递数据. ...
- *fetch(_, { call, put }) { --- generator
effects: { *fetch(_, { call, put }) { const response = yield call(queryUsers); yield put({ type: 'sa ...
- EPX-Studio调用Dll模块
procedure TForm1.BitBtn1Click(Sender: TObject); var REP : IExcelPanelXDisp; modulePath:string; begin ...
- JS事件冒泡及阻止
事件冒泡及阻止 当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到window,当然其传播的是事件,绑定的执行函数并不会传播,如果父级没有绑定事件函数,就算传递了事件,也不会有什么表 ...