Written with StackEdit.

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。

Solution

  • 树形dp的入门题.(确定是省选的题?)
  • 注意到次数限制\(t\)其实就是到达该点后,最多再进入它的\(t-1\)颗子树.
  • 令\(f[i]\)表示从\(i\)节点向下方走,最后回到\(i\)的最大收益.
  • 令\(g[i]\)表示取得\(f[i]\)这个最大收益的方案是否唯一.
  • 考虑状态转移,若记每个点的收益为\(w\),停留次数为\(t\).
  • 则\(f[i]\)就为\(w[i]\)加上最多\(t-1\)个子树的收益.将儿子按照\(f\)排序即可.
  • \(g[i]\)在满足以下\(3\)中情况中任意一种时为\(0\):
    • 某个取得的儿子\(f\)值为\(0\).(我们可以选择不取它).
    • 某个取得的儿子\(g\)值为\(0\).(我们在这颗子树中有不同的路径)
    • 下个未选的儿子(如果有)和最后选择的儿子\(f\)值相同.(可以替换).
  • 其他时候\(g[i]\)均为\(1\).
  • 答案即为\(f[1],g[1]\).
#include<bits/stdc++.h>
#define inf 0x7fffffff
#define yes "solution is unique"
#define no "solution is not unique"
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int MAXN=1e5+10;
int cnt=0,head[MAXN];
int to[MAXN<<1],nx[MAXN<<1];
inline void add(int u,int v)
{
++cnt;
to[cnt]=v;
nx[cnt]=head[u];
head[u]=cnt;
}
int n;
int t[MAXN],w[MAXN];
int f[MAXN],g[MAXN];
int cmp(const int &x,const int &y)
{
return f[x]>f[y];
}
// 1 stands for unique
// 0 stands for not unique
void dfs(int u,int fa)
{
f[u]=w[u];
g[u]=1;
vector<int> sons;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v==fa)
continue;
dfs(v,u);
sons.push_back(v);
}
sort(sons.begin(),sons.end(),cmp);
int siz=sons.size();
int lim=min(t[u],siz);
int sel=0;
for(int i=0;i<lim;++i)
{
if(f[sons[i]]<0)//若f值开始为负,后面都不能选择
break;
f[u]+=f[sons[i]];
++sel;
if(f[sons[i]]==0)
g[u]=0;
if(g[sons[i]]==0)
g[u]=0;
}
if(sel<siz && f[sons[sel-1]]==f[sons[sel]])
g[u]=0;
}
int main()
{
n=read();
for(int i=2;i<=n;++i)
w[i]=read();
for(int i=2;i<=n;++i)
t[i]=read(),--t[i];//t[i]表示i最多能选取多少个子树
for(int i=1;i<n;++i)
{
int u=read(),v=read();
add(u,v);
add(v,u);
}
w[1]=0;
t[1]=inf;
dfs(1,0);
printf("%d\n%s\n",f[1],g[1]?yes:no);
return 0;
}

bzoj 4472 salesman的更多相关文章

  1. BZOJ 4472 salesman 题解

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

  2. 【树形dp】 Bzoj 4472 Salesman

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

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

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

  4. bzoj 4472: [Jsoi2015]salesman【树形dp+贪心】

    一个点,设f[u]为要取最大值显然是前最大停留次数-1个儿子的正数f和,排个序贪心即可 判重的话就是看没选的里面是否有和选了的里面f值相同的,有的话就是一.注意在选的时候要把加进f的儿子的g合并上去 ...

  5. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  6. 「JSOI2015」salesman

    「JSOI2015」salesman 传送门 显然我们为了使收益最大化就直接从子树中选大的就好了. 到达次数的限制就是限制了可以选的子树的数量,因为每次回溯上来都会减一次到达次数. 多种方案的判断就是 ...

  7. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  8. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  9. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

随机推荐

  1. ASP.NET MVC 在项目中使用面包屑导航

    给框架添加一个面包屑导航 1.创建一个类 using System; using System.Collections.Generic; using System.Linq; using System ...

  2. 20145109 《Java程序设计》第四周学习总结

    20145109 <Java程序设计>第四周学习总结 教材学习内容总结 Chapter 6 Inheritance & Polymorphism What is Inheritan ...

  3. React Native常用组件之ListView组件

    学习iOS开发的同学应该都知道UITableView,几乎每个APP中都有它的存在,而且衍生出各种形态:那么同样,ListView就是在React Native中的tableView,而且更加简单和灵 ...

  4. HDU 1176 免费馅饼 简单动态规划

    世道很简单的动态规划,但是却错了,让我很无语,改来改去还是不对,第二天有写就对了,之后我就耐着性子慢慢比较之前的错误代码,发现 第一次错:纯粹用了a[i][j]+=max3(a[i+1][j-1], ...

  5. Spark Configuration配置

    Spark可以通过三种方式配置系统: 通过SparkConf对象, 或者Java系统属性配置Spark的应用参数 通过每个节点上的conf/spark-env.sh脚本为每台机器配置环境变量 通过lo ...

  6. IDEA 修改JSP和后端数据后,页面刷新可以实时更新

    情况:刚开始使用IDEA进行开发时,发现修改JSP页面或者后端数据后,再刷新浏览器页面,发现没有变化,页面无更新. 这样就导致不得不频繁重启tomcat服务器.非常麻烦 解决方法: 步骤1. 先设置t ...

  7. PAT1063. Set Similarity (25)

    来自http://blog.csdn.net/tiantangrenjian/article/details/16868399 set_intersection 交集  set_union 并集  s ...

  8. 多线程-栅栏CyclicBarrier

    上一篇总结了闭锁CountDownLatch,这一篇总结一下栅栏CyclicBarrier.它们两者之间的区别主要是,闭锁是等待一个事件发生,比如上一篇的田径比赛,运动员等待裁判哨声一响就可以开始跑, ...

  9. LongestValidParentheses, 求最长合法括号子串长度-----同类问题ValidParentheses,GenerateParentheses

    问题描述:求括号字符串中最长合法子串长度.例如:()((),返回2,而不是4. 算法分析:还是利用栈,和判断合法括号对是一样的. public static int longestValidParen ...

  10. Echarts的赋值,设置数据

    柱形图案例的赋值 相关文档参考:https://blog.csdn.net/yangsitong1314/article/details/76984616 <div class="ma ...