[BZOJ4472]-树形&贪心
来源:互联网 发布:淘宝优站报名入口 编辑:程序博客网 时间:2024/06/05 09:14
last update at 2017.11.6
1.规范了板式
2.修改了部分口胡的语句
说在前面
这个水题写了我一个白天= =
就因为建边忘了建双向边,以为所有给的边都是father->son的
简直*了狗(狗:woc关我啥事)
题意:
给你一棵含有n个节点的树,每个节点有权值(可正可负),并且每个节点有路过次数上限。仅在第一次路过某个节点后,获得该节点的权值。现问从1号节点出发,在树上随便跑(可以不进入某些节点)后能获得的最大收益,并输出方案是否唯一。
若唯一,输出solution is unique
else,输出solution is not unique
方案唯一是指:至少有两个方案可以达到该权值,并且此两方案路过的节点不至少有一个点不同。
输入
第一行一个整数:n,代表总节点数。
第二行n-1个整数,代表第二到第n个点的权值
第三行n-1个整数,代表第二到第n各节点最大可路过次数
接下来n-1行,每行两个整数,代表此两节点之间有一条边。
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
数据保证每个节点路过次数不小于二,并且从1可以到达任意一点,即整个图是联通的,不是森林。1号节点进入次数不限,权值为0.
输出
9
solution is unique
解法
一开始看到这个题可能会想到树形背包
然而这道题因为不确定选点的个数,因此背包的容积是不确定的,因此不能用背包做。
看到这里,请读者仔细思考一下该题正解:
·
·
·
·
·
·
·
·
·
·
·
如果还没想出来–>请回头看一下本文标题
.
.
.
.
.
.
.
.
.
.
.
可以发现,节点的权值有正有负,由于我们路过点的次数有限,那么我们肯定是尽量的把正权值的点选完
于是思路出来了:
递归处理每个子节点,然后把已经处理好的子节点的最优解从大到小排序,如果正权值已经选完,或者选的节点到达上限,就退出循环。
那么如何确定解是不是唯一呢?
在把子树的最大收益计算出来之后,是排了一遍 续....续1s!序的。如果当前选择的最后一个节点,和第一个me没选的节点收益一样,那么方案不唯一。如果me选中的节点中有收益为0的,那么方案也不唯一。
下面是自带大常数的代码:
其中,pro[i]代表的是点i的初始利润
dp数组为处理之后,路过改点获得的最大收益
isnotuni==is not unique
tim[i]表示i点最大可经过次数
其余的应该都能懂 ~
/* ************************************************************* Problem: 4472 User: Izumihanako Language: C++ Result: Accepted Time:336 ms Memory:4340 kb*************************************************************** */#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;int n,pro[100001],tim[100001],head[100001],tw=0;int dp[100001],isnotuni[100001];struct node{ int pre,to;}w[200001];int comp(const pair<int,int > &a,const pair<int,int > &b){ if(a.first<b.first) return 0; return 1;}void In(int t1,int t2){ w[++tw].pre=head[t1]; w[tw].to=t2; head[t1]=tw;}void work(int u,int f){ vector< pair<int,int> > Ve; Ve.clear(); for(int i=head[u];i;i=w[i].pre){ int v=w[i].to; if(v==f) continue; work(v,u); Ve.push_back(make_pair<int,int>(dp[v],v)); } sort( Ve.begin(), Ve.end(), comp); int i=0,R=Ve.size()-1; for(;i<=R&&i+2<=tim[u]&&Ve[i].first>=0;i++){ isnotuni[u]|=isnotuni[Ve[i].second]; dp[u]+=Ve[i].first; } if(i>0&&i!=Ve.size()) isnotuni[u]|=(Ve[i-1].first==Ve[i].first ? 1 : 0); if(i>0&&Ve[i-1].first==0) isnotuni[u]=1; dp[u]+=pro[u];}inline int read(){ int data=0,w=1; char ch=0; while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar(); if(ch=='-') w=-1,ch=getchar(); while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar(); return data*w;}int main(){ int t1,t2; scanf("%d",&n); for(int i=2;i<=n;i++) pro[i]=read(); for(int i=2;i<=n;i++) tim[i]=read(); tim[1]=0x3f3f3f3f; for(int i=2;i<=n;i++){ t1=read();t2=read(); In(t1,t2); In(t2,t1); } work(1,0); printf("%d\n",dp[1]); if(isnotuni[1]==1) printf("solution is not unique"); else printf("solution is unique"); return 0;}
- [BZOJ4472]-树形&贪心
- [bzoj4472][Jsoi2015]salesman 树形DP
- BZOJ4472[Jsoi2015] salesman 解题报告【树形DP】
- 【树形贪心】【UVA1267】Network
- poj 1694 树形贪心
- poj 1849 贪心 ||树形dp
- bzoj 1060(贪心+树形DP)
- 【Codeforces708C】【树形dp】【贪心】Centroids
- 51NOD1378 树形DP + 贪心
- 【APIO2010T2】巡逻-贪心+树形DP
- BZOJ3037 创世纪 [贪心][树形DP]
- Poj1463 及 Poj3659 树形贪心建立解
- HDU 4313 Matrix 贪心 || 树形dp
- hdu - 4313 - Matrix - 树形dp 或者 贪心
- acdream 1015Double Kings 树形结构 贪心
- spoj1435 - Vertex Cover(贪心or树形dp)
- poj 2057 树形DP+一点贪心
- Codeforces 77C 树形dp + 贪心
- 理解字节序
- 不用正则,得到url中的HOST,端口,路径,查询参数
- 序列化和反序列化
- iOS备忘录之获取APPStore上的APPID
- ORA-02292:integrity constraint(xx) violated
- [BZOJ4472]-树形&贪心
- Connect函数
- EAS,BOS,校验业务单据是否已经通过BOTP生成指定下游单据
- https原理通俗了解
- Caysn打印机IOS平台打印开发包及示例程序_20170610
- Java数据结构与算法---链表的实现
- Solr安装
- leetcode 118. Pascal's Triangle
- Java for Web学习笔记(六二):Controller替代Servlet(4)方法返回值