Description

某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇
之间都只有唯一的可能经过其它城镇的路线。 小T 可以准确地估计出在每个城镇停留的净收
益。这些净收益可能是负数,即推销商品的利润抵不上花费。由于交通不便,小T经过每个
城镇都需要停留,在每个城镇的停留次数与在该地的净收益无关,因为很多费用不是计次收
取的,而每个城镇对小T的商品需求也是相对固定的,停留一次后就饱和了。每个城镇为了
强化治安,对外地人的最多停留次数有严格的规定。请你帮小T 设计一个收益最大的巡回方
案,即从家乡出发,在经过的每个城镇停留,最后回到家乡的旅行方案。你的程序只需输出
最大收益,以及最优方案是否唯一。方案并不包括路线的细节,方案相同的标准是选择经过
并停留的城镇是否相同。因为取消巡回也是一种方案,因此最大收益不会是负数。小T 在家
乡净收益是零,因为在家乡是本地人,家乡对小 T当然没有停留次数的限制。

Input

输入的第一行是一个正整数n(5<=n<=100000),表示城镇数目。城镇以1到n的数命名。小T 的家乡命
名为1。第二行和第三行都包含以空格隔开的n-1个整数,第二行的第i个数表示在城镇
i+1停留的净收益。第三行的第i个数表示城镇i+1规定的最大停留次数。所有的最大
停留次数都不小于2。接下来的n-1行每行两个1到n的正整数x,y,之间以一个空格
隔开,表示x,y之间有一条不经过其它城镇的双向道路。输入数据保证所有城镇是连通的。

Output

输出有两行,第一行包含一个自然数,表示巡回旅行的最大收益。如果该方案唯一,在
第二行输出“solution is unique”,否则在第二行输出“solution is not unique”。

Sample Input

9
-3 -4 2 4 -2 3 4 6
4 4 2 2 2 2 2 2
1 2
1 3
1 4
2 5
2 6
3 7
4 8
4 9

Sample Output

9
solution is unique
//最佳路线包括城镇 1,2, 4, 5, 9。
 
这道树形dp好清奇……
考虑一下,设$cnt[i]$表示在$i$点的最多停留次数,那么$cnt[i]-1$就是最多能进入的子树的个数(因为到达时必须停留一次)
然后发现子树里不管怎么走,对该点的停留次数的影响都是$1$,所以每一个子树里肯定要走出最优的方案
那么我们设$dp[v]$表示$v$这一整棵子树的最优方案的权值,考虑从$u$点如何选择才能使该点最优
首先自己必须选,然后把所有儿子的$dp$值排个序,取前$cnt[u]-1$个或一直取到第一个$dp$为0的值,不难发现没有方案会比他更优
然后存儿子的$dp$值的话可以用vector
现在的问题就是怎么判断方案是否唯一
首先,如果儿子的$dp$值的前$cnt[u]-1$个里有0,那么该点的最优方案肯定不唯一(因为0那个点可以选或不选)
其次,如果第$cnt[u]-1$和$cnt[u]$个都大于0且相等,那么方案也不唯一(因为这两个都可以选)
然后如果子树的方案不唯一,自己的方案也不唯一
所以用结构体存储子树的$dp$,分别记录最大权值和方案是否唯一,不断向上dp即可
交上去竟然1A了……
 //minamoto
#include<bits/stdc++.h>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=;
struct node{
int v,f;
node(){}
node(int v,int f):v(v),f(f){}
inline node operator +(const node &b)const
{return node(v+b.v,f|b.f|(b.v==));}
inline bool operator <(const node &b)const
{return v>b.v;}
inline bool operator ==(const node &b)const
{return v==b.v;}
inline void operator +=(const node &b)
{*this=*this+b;}
}dp[N];
int head[N],Next[N<<],ver[N<<],tot;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
vector<node> val[N];int a[N],cnt[N],n,m;
void dfs(int u,int fa){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];if(v==fa) continue;
dfs(v,u);
val[u].push_back(dp[v]);
}
dp[u]=node(a[u],);
sort(val[u].begin(),val[u].end());
int i=,s=val[u].size(),k=cnt[u]-;
for(;i<s&&i<k&&val[u][i].v>=;++i) dp[u]+=val[u][i];
if(i<s-&&val[u][i].v>&&val[u][i]==val[u][i+]) dp[u].f=;
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i) a[i]=read();a[]=;
for(int i=;i<=n;++i) cnt[i]=read();cnt[]=n+;
for(int i=,u,v;i<n;++i)
u=read(),v=read(),add(u,v),add(v,u);
dfs(,);
printf("%d\n",dp[].v);
puts(dp[].f?"solution is not unique":"solution is unique");
return ;
}

bzoj4472: [Jsoi2015]salesman(树形dp)的更多相关文章

  1. BZOJ 4472 [Jsoi2015]salesman(树形DP)

    4472: [Jsoi2015]salesman Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 417  Solved: 192[Submit][St ...

  2. bzoj4472:[Jsoi2015]salesman

    传送门 树形dp 对于每个点维护其子节点的走法是否唯一,每次取最大的并且不为负的(停留次数-1)个子儿子权值,然后判断走法是否唯一 假如有子节点的权值为0,走法也不唯一 代码: #include< ...

  3. 【题解】 bzoj4472: [Jsoi2015]salesman (动态规划)

    bzoj4472,懒得复制,戳我戳我 Solution: 题面意思:从\(1\)号节点出发,每到一个节点就必须停下,获得节点权值(每个节点只会获得一次),每个点有个规定的停留次数,求最大可获得多大权值 ...

  4. BZOJ4472 JSOI2015salesman(树形dp)

    相当于选一个包含根的连通块使权值和最大,且每个点的儿子选取数量有限制.那么显然贪心的在所有子树中选比较大的就可以了.至于方案是否唯一只需要看选的子树是否可以替换,注意dp值为0的情况. #includ ...

  5. 【BZOJ4472】salesman(树形DP)

    题意: 给定一颗有点权的树,每个树上的节点最多能走到lim[u]次,求一条路径,使路径上的点权和最大,每个节点上的点权如果走了多次只能算一次.还要求方案是否唯一. 思路:每个点只能取lim[u]-1个 ...

  6. [bzoj4472][树形DP] Salesman

    题目 原地址 解说 刚看完这道题感觉还是挺乱的,可能那时候脑子不太清醒,一度觉得自己又要重拾Tarjan了.当然最后还是发觉应该用树形DP. (以下dp[u]代表以u为根的包括自己在内的子树的最大利润 ...

  7. 【树形DP】JSOI BZOJ4472 salesman

    题目内容 vjudge链接 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇 之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收 益.这些 ...

  8. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  9. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

随机推荐

  1. 《STL源代码剖析》---stl_deque.h阅读笔记(2)

    看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque. ...

  2. LeetCode(26)题解:Remove Duplicates from Sorted Array

    https://leetcode.com/problems/remove-duplicates-from-sorted-array/ Given a sorted array, remove the ...

  3. python day- 10 动态参数 函数的嵌套 命名空间和作用域 global和nolocal

    一.动态参数: 动态参数是形参的一类 分为:动态位置参数(* + 函数名)表示 调用后返回的是元祖 动态关键字参数(** + 函数名)表示 形参的排列顺序: 位置参数     >   动态位置参 ...

  4. python day- 7 进本数据类型的先关知识点 set集合 深浅拷贝

    一.基本数据类型相关知识 1.str.    join()函数 关于字符串 a = "我爱北京" b = a.join("真的")            将&q ...

  5. MRP-MD04 中的函数

    1.需求溯源 : MD_PEGGING_NODIALOG 2.实时库存 : MD_STOCK_REQUIREMENTS_LIST_API 这个函数中MDPSX 和 MDEZX 是通过 MDPS 的 I ...

  6. throw 、throws 简介

    抛出异常抛出异常有三种形式,一是throw,一个throws,还有一种系统自动抛异常.下面它们之间的异同.系统自动抛异常当程序语句出现一些逻辑错误.主义错误或类型转换错误时,系统会自动抛出异常.如: ...

  7. fminunc

    options = optimset('GradObj', 'on', 'MaxIter', 400); % Run fminunc to obtain the optimal theta% This ...

  8. ActiveMQ 安全认证

    修改配置文件 位置: apache-activemq-5.9.0/conf/ vi activemq.xml 在<broker xmlns="http://activemq.apach ...

  9. mysql 查询表死锁 和结束死锁的表步骤以及锁表等级

    1.查询是否锁表show OPEN TABLES where In_use > 0; 2.查询进程 show processlist  查询到相对应的进程===然后 kill    id 补充: ...

  10. vue2-editor富文本基础使用方法

    vue2-editor的入门使用准备工作: 使用 npm install vue2-editor --save 安装到项目中去: 使用 在需要的单文件内引入 import { VueEditor } ...