BZOJ4472
某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇
之间都只有唯一的可能经过其它城镇的路线。 小T 可以准确地估计出在每个城镇停留的净收
益。这些净收益可能是负数,即推销商品的利润抵不上花费。由于交通不便,小T经过每个
城镇都需要停留,在每个城镇的停留次数与在该地的净收益无关,因为很多费用不是计次收
取的,而每个城镇对小T的商品需求也是相对固定的,停留一次后就饱和了。每个城镇为了
强化治安,对外地人的最多停留次数有严格的规定。请你帮小T 设计一个收益最大的巡回方
案,即从家乡出发,在经过的每个城镇停留,最后回到家乡的旅行方案。你的程序只需输出
最大收益,以及最优方案是否唯一。方案并不包括路线的细节,方案相同的标准是选择经过
并停留的城镇是否相同。因为取消巡回也是一种方案,因此最大收益不会是负数。小T 在家
乡净收益是零,因为在家乡是本地人,家乡对小 T当然没有停留次数的限制。
树上贪心
dp[x],表示以x为根的子树的最大值,g[x]表示dp[x]确定最大时,是否出现方案有多个(只要判断最优方案中某个可选的do值为0)
每层维护一个堆,将dp[y],g[y],扔进堆中,取前cnt[x] - 1个,直到有0出现为止
code:
#include <cstring>
#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int MAXX = 100100;
int hed[MAXX], ver[MAXX << 1], nxt[MAXX << 1], val[MAXX], cnt[MAXX], dp[MAXX];
bool g[MAXX];
int n, tot;
inline void add(int x, int y) {
ver[++tot] = y;
nxt[tot] = hed[x];
hed[x] = tot;
}
inline void dfs(int x,int f) {
priority_queue<pair<int ,int > > q;
for (int i = hed[x]; i; i = nxt[i]) {
int y = ver[i];
if (y == f) continue;
dfs (y, x);
q.push(make_pair(dp[y],g[y]));
}
int num = 0;
int now = 0;
bool flag = 0;
while (!q.empty() && num < cnt[x] - 1) {
if(q.top().first < 0) break;
else if (q.top().first == 0) {
flag |= 1;
break;
}else {
now += q.top().first;
flag |= q.top().second;
}
q.pop();
num++;
}
dp[x] = now + val[x]; g[x] = flag;
}
int main() {
scanf("%d", &n);
cnt[1] = 1e9;
for (int i = 2; i <= n; ++i) scanf("%d", &val[i]);
for (int i = 2; i <= n; ++i) scanf("%d", &cnt[i]);
for (int i = 1; i < n; ++i) {
int x, y;
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
dfs(1, 0);
printf("%d\n",dp[1]);
if (g[1] == 0) printf("solution is unique");
else printf("solution is not unique");
return 0;
}
BZOJ4472的更多相关文章
- 【题解】 bzoj4472: [Jsoi2015]salesman (动态规划)
bzoj4472,懒得复制,戳我戳我 Solution: 题面意思:从\(1\)号节点出发,每到一个节点就必须停下,获得节点权值(每个节点只会获得一次),每个点有个规定的停留次数,求最大可获得多大权值 ...
- BZOJ4472 JSOI2015salesman(树形dp)
相当于选一个包含根的连通块使权值和最大,且每个点的儿子选取数量有限制.那么显然贪心的在所有子树中选比较大的就可以了.至于方案是否唯一只需要看选的子树是否可以替换,注意dp值为0的情况. #includ ...
- 【BZOJ4472】salesman(树形DP)
题意: 给定一颗有点权的树,每个树上的节点最多能走到lim[u]次,求一条路径,使路径上的点权和最大,每个节点上的点权如果走了多次只能算一次.还要求方案是否唯一. 思路:每个点只能取lim[u]-1个 ...
- bzoj4472:[Jsoi2015]salesman
传送门 树形dp 对于每个点维护其子节点的走法是否唯一,每次取最大的并且不为负的(停留次数-1)个子儿子权值,然后判断走法是否唯一 假如有子节点的权值为0,走法也不唯一 代码: #include< ...
- bzoj4472: [Jsoi2015]salesman(树形dp)
Description 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收益.这些净收益可 ...
- 题解【BZOJ4472】[JSOI2015]salesman
题面 树形\(\text{DP}\)与贪心的结合. 首先考虑树形\(\text{DP}\). 设\(dp_i\)表示从\(i\)出发,访问\(i\)的子树,并且最后回到\(i\)能获得的最大收益. 转 ...
- [bzoj4472][树形DP] Salesman
题目 原地址 解说 刚看完这道题感觉还是挺乱的,可能那时候脑子不太清醒,一度觉得自己又要重拾Tarjan了.当然最后还是发觉应该用树形DP. (以下dp[u]代表以u为根的包括自己在内的子树的最大利润 ...
- JSOI BZOJ4472 salesman
题目传送门 题目大意 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收益.这些净收益可能 ...
- 【树形DP】JSOI BZOJ4472 salesman
题目内容 vjudge链接 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇 之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收 益.这些 ...
随机推荐
- xBIM 基础14 使用LINQ实现最佳性能(优化查询)
系列目录 [已更新最新开发文章,点击查看详细] LINQ代表语言集成查询,它是3.5版以来的.NET Framework的一部分.它实现延迟执行,这意味着您可以链接查询语句,并且在您实际迭代结 ...
- js小知识 delete操作符
说明:delete操作符用于删除对象的某个属性. 语法: delete object.property //删除 对象.属性 delete object['property'] //删除 对象['属性 ...
- (转载)android控件之WebView控件缩小
android控件之WebView控件缩小 作者: 字体:[增加 减小] 类型:转载 时间:2013-05-16我要评论 发现这个控件挺好用,能自已控制进度条,而且这个控件的功能非常壮大,先上个简单的 ...
- MySQL用户添加和分配权限
mysql数据库insertdelete服务器file mysql> grant 权限1,权限2,…权限n on 数据库名称.表名称 to 用户名@用户地址 identified by ‘连接口 ...
- IPv6第二层寻址,IPv6接口要求
1. IPv6第二层寻址 IPV6地址以两种方式与第2层地址相关.第一种方式是IPV6独有的,提供了从第2层地址构建接口ID的机制.第二种方式对IPv4和IPV6都是一样的,提供了将一个IP组播地址映 ...
- 路飞学城Python-Day15(模块二思维导图)
- mysql 查询格式化时间
select DATE_FORMAT(addtime,'$m %d %Y') from tablename 输出:01 28 2019 数据库时间格式:2019-01-28 15:01:20
- (2016北京集训十二)【xsy1542】疯狂求导
题解: 这题看起来很难...但是实际上并没有想象中的那么难 第一眼看上去不会求导公式怎么办?不要紧,题目背景非常良心的给出了题目中的导数计算公式 求完导合并同类项很恶心怎么办?不要紧,样例解释说明了不 ...
- java 导出百万数据到excel
@RequestMapping("export") public void write(HttpServletRequest request,HttpServletResponse ...
- mysql日期加减运算
MySQL 日期类型MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型 存储空间 日期格式 日期范围 --------- ...