【XSY1905】【XSY2761】新访问计划 二分 树型DP
题目描述
给你一棵树,你要从\(1\)号点出发,经过这棵树的每条边至少一次,最后回到\(1\)号点,经过一条边要花费\(w_i\)的时间。
你还可以乘车,从一个点取另一个点,需要花费\(c\)的时间。
你最多做\(k\)次车。
问最短时间。
\(k\leq n\leq 20000,w,c\leq 50000\)
题解
我们考虑把最终路线中坐车的部分替换成走路。
那么显然不会经过一条边超过两次。
但是每条边都要经过者少一次,所以每条边只能被一个坐车的路线覆盖。
所以我们要选择不超过\(k\)条不相交的链,把这些链用\(c\)的代价覆盖掉。
可以用树上背包做。
时间复杂度:\(O(nk)\)
还有有一个网络流的做法:每次找树上最长链,然后用\(c\)的代价覆盖掉,即把路径上的边权取反。
正解:
如果我们可以调整乘车的代价,并把乘车次数设为无限次,那么当最优方案的乘车次数不超过\(k\)时最优方案的路线就是最优路线。
这个东西可以用一次树型DP解决。
设\(f_i\)为从\(i\)开始遍历以\(i\)为根的子树并回到\(i\)的最小代价和乘车次数,\(g_i\)为从\(i\)开始遍历以\(i\)为根的子树并乘车回到\(i\)的最小代价和乘车次数。
然后随便DP一下就行了。
可以观察到,乘车次数是随着乘车代价单调下降的(可能是非连续的),所以可以二分乘车代价,得到答案。
时间复杂度:\(O(n\log nw)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<utility>
using namespace std;
typedef unsigned un;
typedef pair<un,un> pii;
const int inf=0x3fffffff;
vector<pii> t[100010];
int n,k,c;
un cost;
pii f[100010];
pii g[100010];
pii operator +(pii a,pii b)
{
return pii(a.first+b.first,a.second+b.second);
}
pii operator -(pii a,pii b)
{
return pii(a.first-b.first,a.second-b.second);
}
void dp(int u,int fa)
{
f[u]=pii(0,0);
g[u]=pii(cost,1);
for(auto a:t[u])
if(a.first!=fa)
{
int v=a.first;
int w=a.second;
dp(v,u);
pii f1=pii(inf,0);
pii g1=pii(inf,0);
f1=min(f1,f[u]+f[v]+pii(w,0));
f1=min(f1,f[u]+f[v]+pii(cost,1));
f1=min(f1,f[u]+g[v]);
f1=min(f1,g[u]+f[v]);
f1=min(f1,g[u]+g[v]-pii(cost,1));
g1=min(g1,f[u]+f[v]+pii(cost,1));
g1=min(g1,f[u]+g[v]);
g1=min(g1,g[u]+f[v]+pii(w,0));
g1=min(g1,g[u]+g[v]);
f[u]=f1;
g[u]=g1;
}
}
void solve()
{
for(int i=1;i<=n;i++)
t[i].clear();
int x,y,z;
int sum=0;
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
x++;
y++;
t[x].push_back(pii(y,z));
t[y].push_back(pii(x,z));
sum+=z;
}
cost=c;
dp(1,0);
if(f[1].second<=k)
{
printf("%d\n",sum+f[1].first);
return;
}
int l=0,r=inf;
while(l<r)
{
cost=(l+r)>>1;
dp(1,0);
if(f[1].second>k)
l=cost+1;
else
r=cost;
}
cost=l;
dp(1,0);
int ans=f[1].first-k*(l-c)+sum;
printf("%d\n",ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
#endif
while(~scanf("%d%d%d",&n,&k,&c))
solve();
return 0;
}
【XSY1905】【XSY2761】新访问计划 二分 树型DP的更多相关文章
- BZOJ 1564 :[NOI2009]二叉查找树(树型DP)
二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结 ...
- 【POJ 2486】 Apple Tree(树型dp)
[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8981 Acce ...
- BZOJ 2286 消耗战 - 虚树 + 树型dp
传送门 题目大意: 每次给出k个特殊点,回答将这些特殊点与根节点断开至少需要多少代价. 题目分析: 虚树入门 + 树型dp: 刚刚学习完虚树(好文),就来这道入门题签个到. 虚树就是将树中的一些关键点 ...
- 初学树型dp
树型DP DFS的回溯是树形DP的重点以及核心,当回溯结束后,root的子树已经被遍历完并处理完了.这便是树形DP的最重要的特点 自己认为应该注意的点 好多人都说在更新当前节点时,它的儿子结点都给更新 ...
- ACM之路(13)—— 树型dp
最近刷了一套(5题)的树型dp题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=116767#overview,算是入了个门,做下总结. ...
- 【题解】Luogu p2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat 树型dp
题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
- 洛谷P3354 Riv河流 [IOI2005] 树型dp
正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ...
随机推荐
- form,ajax注册,logging日志使用
一.form表单类型提交注册信息 二.ajax版本提交注册信息 <!DOCTYPE html> <html lang="en"> <head> ...
- Python中的鸡肋多线程
作者:DarrenChan陈驰链接:https://www.zhihu.com/question/23474039/answer/269526476来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...
- 一些Cassandra+YCSB异常
这两天一直在用YCSB.昨天还可以用的YCSB,今天在测试Cassandra时遇到问题了. 环境是在公用局域网的一台debian机器,YCSB和Cassandra都在这台机器上.异常是开始运行YCSB ...
- Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包
1.UDP通信编解码类 (1) 类 # ------------------UDP通信解码编码类------------------------ from socket import * class ...
- Java Core - 序列化和反序列化
把对象转换为字节序列的过程称为对象的序列化 把字节序列恢复成对象的过程称为对象的反序列化 一.对象的序列化的应用: 1.把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中. 2.在网络上传送对象 ...
- Linux系统mysql使用(二)
一.查看某数据库的表 # 假设此时数据库名为hiveuse hive; show tables;
- Eclipse Todo Tasks 任务试图
java - Find TODO tags in Eclipse - Stack Overflowhttps://stackoverflow.com/questions/16903046/find-t ...
- bootstrap 弹窗或者提示框插件 bootstrap-growl 和bootstrap-notify
Bootstrap简单好用的页面右上角咆哮提示框 - daidaineteasy的专栏 - CSDN博客https://blog.csdn.net/daidaineteasy/article/deta ...
- [转帖]迎战AMD 7nm 64核EPYC 英特尔至强也玩起了胶水以及性价比
迎战AMD 7nm 64核EPYC 英特尔至强也玩起了胶水以及性价比 Intel 最强CPU 从最开始的双核 到现在的 28核 发展迅猛. https://www.cnbeta.com/article ...
- jQuery-mobilevalidate使用 的一些心得,小小总结
在做M站时比较纠结的是表单验证,不像pc端,移动端的验证要求插件更小更轻量,更加灵活,说不定是冒气泡的报错提示?! 介绍一款好用的移动端的表单验证插件:jQuery-mobilevalidate: 代 ...