[八省联考2018]林克卡特树lct——WQS二分
一看这种题就不是lct。。。
除了直径好拿分,别的都难做。
所以必须转化
突破口在于:连“0”边
对于k=0,我们求直径
k=1,对于(p,q)一定是从p出发,走一段原树,走0(或不走),再走一段原树,所以要最大化原树的值的和。
选择最大两条 点不相交的链(注意:可以选择一个点,这时候链长为0)。然后一定可以首尾连起来得到答案
k更大的时候,选择最大的k+1条两两不相交的路径,然后一定存在方案使之连接起来,一定是最优解。(因为如果实际上最优解不用走k条0边,一定会把这些0边随便连一连废掉,对应选择一个点作为链)
所以,求最大的k+1条两两点不相交的路径。
点不相交,每次贪心取直径然后取反其实不好做。而且显然扩展性太差
树形DP
f[x][0/1/2][k]表示x为根的子树,从下面连接到x的度数是0/1/2,用k条链的最优解。特别地,从x开始往上的链归入f[x][1][*]。
转移时候枚举和当前儿子怎么连就好了。
看上去已经不能优化了。
然鹅
可以发现,如果f[x]函数表示选择x个链的最大总和
这是一个上凸函数!
就可以WQS二分了
具体地,每个链的额外花费mid的代价
然后求全局的最高点。没了k的限制就好做了
f[x][0/1/2]
(PS:
1.这个题如果连接的新边不是0应该也可以,但是必须是正数,负数的话转化就不对了,不一定走K次新边最优
2.如果k是一个区间也许也可以?
)
代码:
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=3e5+;
const ll inf=0x3f3f3f3f3f3f3f3f;
int n,k;
int b[N][];
struct node{
int nxt,to;
ll val;
}e[*N];
int hd[N],cnt;
void add(int x,int y,ll z){
e[++cnt].nxt=hd[x];
e[cnt].val=z;
e[cnt].to=y;
hd[x]=cnt;
}
struct dp{
ll v;
int c;
dp(){}
dp(ll a,int b){
v=a;c=b;
}
dp operator +(const dp &b){
return dp(v+b.v,c+b.c);
}
bool friend operator <(dp a,dp b){
return (a.v<b.v||(a.v==b.v&&a.c<b.c));
}
void clear(){
v=-inf;c=-0x3f3f3f3f;
}
}f[N][];
ll sum;
void dfs(int x,int fa,ll mid){
f[x][].clear();
f[x][].clear();
f[x][].v=,f[x][].c=;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
dfs(y,x,mid);
f[x][]=max(f[x][]+f[y][],f[x][]+f[y][]+dp(e[i].val+mid,-));
f[x][]=max(f[x][]+f[y][],f[x][]+f[y][]+dp(e[i].val,));
f[x][]=f[x][]+f[y][];
}
f[x][]=max(f[x][],f[x][]+dp(-mid,));
f[x][]=max(f[x][],max(f[x][],f[x][]));
}
int check(ll mid){
memset(hd,,sizeof hd);cnt=;
sum=;
for(reg i=;i<n;++i){
add(b[i][],b[i][],b[i][]);
add(b[i][],b[i][],b[i][]);
}
dfs(,,mid);
// for(reg i=1;i<=n;++i){
// cout<<" i "<<i<<" : "<<f[i][0].v<<" "<<f[i][0].c<<endl;
// }
sum=f[][].v;
// cout<<" mid "<<mid<<" :: "<<sum<<" "<<f[1][0].c<<endl;
return f[][].c;
}
int main(){
rd(n);rd(k);
++k;
ll l=,r=;
for(reg i=;i<n;++i){
rd(b[i][]);rd(b[i][]);rd(b[i][]);
r+=abs(b[i][]);
}l=-r;
ll ans=-;
while(l<=r){
ll mid=(l+r)/;
if(check(mid)>=k) ans=mid,l=mid+;
else r=mid-;
}
int haha=check(ans);
printf("%lld\n",sum+(ll)k*ans);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/2/20 15:23:18
*/
总结:
1.转化为k+1个链
2.树形dp(经典问题)
3.凸函数,WQS二分
[八省联考2018]林克卡特树lct——WQS二分的更多相关文章
- LuoguP4383 [八省联考2018]林克卡特树lct
LuoguP4383 [八省联考2018]林克卡特树lct https://www.luogu.org/problemnew/show/P4383 分析: 题意等价于选择\(K\)条点不相交的链,使得 ...
- 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)
题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做“LCT” 的挑 ...
- [九省联考2018]林克卡特树(DP+wqs二分)
对于k=0和k=1的点,可以直接求树的直径. 然后对于60分,有一个重要的转化:就是求在树中找出k+1条点不相交的链后的最大连续边权和. 这个DP就好.$O(nk^2)$ 然后我们完全不可以想到,将b ...
- 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)
题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...
- P4383 [八省联考2018]林克卡特树lct 树形DP+凸优化/带权二分
$ \color{#0066ff}{ 题目描述 }$ 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的 ...
- luogu4383 [八省联考2018]林克卡特树(带权二分+dp)
link 题目大意:给定你 n 个点的一棵树 (边有边权,边权有正负) 你需要移除 k 条边,并连接 k 条权值为 0 的边,使得连接之后树的直径最大 题解: 根据 [POI2015]MOD 那道题, ...
- [八省联考2018]林克卡特树lct
题解: zhcs的那个题基本上就是抄这个题的,不过背包的分数变成了70分.. 不过得分开来写..因为两个数组不能同时满足 背包的话就是 $f[i][j][0/1]$表示考虑i子树,取j条链,能不能向上 ...
- 洛谷 4383 [八省联考2018]林克卡特树lct——树形DP+带权二分
题目:https://www.luogu.org/problemnew/show/P4383 关于带权二分:https://www.cnblogs.com/flashhu/p/9480669.html ...
- [BZOJ5252][八省联考2018]林克卡特树lct
bzoj(上面可以下数据) luogu description 在树上选出\(k\)条点不相交的链,求最大权值. 一个点也算是一条退化的链,其权值为\(0\). sol 别问我为什么现在才写这题 首先 ...
随机推荐
- 2017-2018-2 20155224『网络对抗技术』Exp7:网络欺诈防范
基础问题回答 问:通常在什么场景下容易受到DNS spoof攻击? 同一局域网下,以及各种公共网络. 问:在日常生活工作中如何防范以上两攻击方法? 答:DNS欺骗攻击是很难防御的,因为这种攻击大多数本 ...
- python中的-1
-1单个使用时表示最后一个: >>> [1,2,3,4][-1] 4 表示范围(区间)时,因为是开区间表示方法,如[0:2]是不包括2的所以 [0:-1]只能访问到倒数第二个(不包括 ...
- Kubernetes学习之路(二十二)之Pod资源调度
目录 Pod资源调度 1.常用的预选策略 2.优选函数 3.节点亲和调度 3.1.节点硬亲和性 3.2.节点软亲和性 4.Pod资源亲和调度 4.1.Pod硬亲和度 4.2.Pod软亲和度 4.3.P ...
- LeetCode 4Sum (Two pointers)
题意 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...
- 云服务器+tomcat+mysql+web项目搭建部署
云服务器+tomcat+mysql+web项目搭建部署 1.老样子,开头墨迹两句. 作为我的第二篇文章,有很多感慨,第一篇人气好低啊,有点小丧气,不过相信我还是经验少,分享的都是浅显的,所以大家可能不 ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- linux内核分析第二次实验
http://blog.sina.com.cn/s/blog_78e559950102wnqp.html
- Docker打DB2 9.7镜像采坑相关
概况:以centos:7.2.1511镜像为基础镜像,使用docker commit方式进行构建 步骤: 运行centos7.2.1511镜像(以特权模式运行,后续内核参数修改必需参数) dock ...
- linux 常用命令-用户、用户组管理
注:本篇只涉及常用命令,全部命令可以通过help帮助查看. (1)type useradd #查看命令属于内部命令还是外部命令,内部命令是嵌在linux的shell中,外部命令存储在路径中 (2) ...
- 计算机启动出现 Invalid Partition Table
计算机启动出现 Invalid Partition Table 解决办法 使用大白菜启动盘进入临时系统,打开程序DiskGenius 如果系统盘(一般为 C 盘)非活动状态,先激活 如果装系统的硬盘不 ...