【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指的是到达那个节点的距离 首先这个一看就 ...
随机推荐
- 小P的金字塔
题目描述 小P感到自己前几天太作了,于是非常有远见的决定为自己建立一座金字塔. 现在他有n种标准长方体的石头,每种石头只有两个,第i种石头是长宽高分别为Xi,Yi,Zi的长方体.由于整个工程只有小P一 ...
- Python—os模块介绍
OS模块 我们平时工作中很常用到的一个模块,通过os模块调用系统命令,获得路径,获取操作系统的类型等都是使用该模块.os 模块提供了很多允许你的程序与操作系统直接交互的功能 得到当前工作目录,即当前P ...
- Mysql 字符集及排序规则
一.字符集 字符集:就是用来定义字符在数据库中的编码的集合. 常见的字符集:utf8.Unicode.GBK.GB2312(支持中文).ASCCI(不支持中文) 二.字符集排序规则 作者本人用 ...
- MySQL 主从同步遇到的问题及解决方案
在做某个项目的时候,使用主从数据库,master负责update.delete.insert操作,而slave负责select操作. 情景1:发表文章与查看文章 可以认为这个项目是一个博客系统,这里就 ...
- vue单页面模板说明文档(3)
Environment Variables Sometimes it is practical to have different config values according to the env ...
- [翻译]在asp.net core2.0 OpenID Connect Handler中丢失了声明(CLaims)?
注:这是一篇翻译,来自这里.这篇文章讲述了在asp.net core2.0中使用openid connect handler的过程中解析不到你想要的claim时,你可以参考这篇文章. Missing ...
- css实现三栏自适应布局(两边固定,中间自适应)以及优缺点
方法一:绝对定位(absolute + margin) 原理:给左右两边的元素设置absolute,这样左右两边的元素脱离标准文档流的控制,中间的元素自然会上来,然后给中间的元素设置margin留出左 ...
- 2 Servlet 细节
1 Servlet 配置详解 ① 由于客户端在浏览器只能通过URL访问web服务器的资源,所以Servlet程序若想被外界访问,必须把Servlet 程序映射到一个URL 地址上,这个工作在项目we ...
- 一条SQL语句执行得很慢的原因有哪些?(转)
一条 SQL 语句执行的很慢,那是每次执行都很慢呢?还是大多数情况下是正常的,偶尔出现很慢呢?所以我觉得,我们还得分以下两种情况来讨论. 1.大多数情况是正常的,只是偶尔会出现很慢的情况. 2.在数据 ...
- K8S入门学习
一.k8s是个什么鬼? k8s全名:kubernetes 它是一个工具,在linux上管理应用生命周期的一个工具. 二.k8s有什么卵用? 1.当你把项目部署到服务器集群上,一台服务器挂了,k8s它可 ...