[八省联考2018]林克卡特树lct

一看这种题就不是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二分的更多相关文章

  1. LuoguP4383 [八省联考2018]林克卡特树lct

    LuoguP4383 [八省联考2018]林克卡特树lct https://www.luogu.org/problemnew/show/P4383 分析: 题意等价于选择\(K\)条点不相交的链,使得 ...

  2. 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)

    题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做“LCT” 的挑 ...

  3. [九省联考2018]林克卡特树(DP+wqs二分)

    对于k=0和k=1的点,可以直接求树的直径. 然后对于60分,有一个重要的转化:就是求在树中找出k+1条点不相交的链后的最大连续边权和. 这个DP就好.$O(nk^2)$ 然后我们完全不可以想到,将b ...

  4. 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)

    题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...

  5. P4383 [八省联考2018]林克卡特树lct 树形DP+凸优化/带权二分

    $ \color{#0066ff}{ 题目描述 }$ 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的 ...

  6. luogu4383 [八省联考2018]林克卡特树(带权二分+dp)

    link 题目大意:给定你 n 个点的一棵树 (边有边权,边权有正负) 你需要移除 k 条边,并连接 k 条权值为 0 的边,使得连接之后树的直径最大 题解: 根据 [POI2015]MOD 那道题, ...

  7. [八省联考2018]林克卡特树lct

    题解: zhcs的那个题基本上就是抄这个题的,不过背包的分数变成了70分.. 不过得分开来写..因为两个数组不能同时满足 背包的话就是 $f[i][j][0/1]$表示考虑i子树,取j条链,能不能向上 ...

  8. 洛谷 4383 [八省联考2018]林克卡特树lct——树形DP+带权二分

    题目:https://www.luogu.org/problemnew/show/P4383 关于带权二分:https://www.cnblogs.com/flashhu/p/9480669.html ...

  9. [BZOJ5252][八省联考2018]林克卡特树lct

    bzoj(上面可以下数据) luogu description 在树上选出\(k\)条点不相交的链,求最大权值. 一个点也算是一条退化的链,其权值为\(0\). sol 别问我为什么现在才写这题 首先 ...

随机推荐

  1. Zabbix实战-简易教程--大型分布式监控系统实现Agent批量快速接入

    一.分布式架构 相信使用zabbix的大神都熟悉他的分布式架构,分布式的优势相当明显,分而治之.比如目前我的架构图如下: 那么,对将要接入监控系统的任何一个agent如何快速定位,并进行接入呢?  问 ...

  2. LeetCode Merge k Sorted Lists (链表)

    题意 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...

  3. React半科普文

    React半科普文 什么是React getting started 文件分离 Server端编译 定义一个组件 使用property 组件嵌套 组件更新 Virtual DOM react nati ...

  4. Json和Map互转,四个包(org.json/net.sf.json/com.google.gson/com.alibaba.fastjson)

    目前使用的(org.json/net.sf.json/com.google.gson/com.alibaba.fastjson)这四种json-map互转,其他的以后在补充.............. ...

  5. 《Macro-Micro Adversarial Network for Human Parsing》论文阅读笔记

    <Macro-Micro Adversarial Network for Human Parsing> 摘要:在人体语义分割中,像素级别的分类损失在其低级局部不一致性和高级语义不一致性方面 ...

  6. PHP完美分页类

    <?php /** file: page.class.php 完美分页类 Page */ class Page { private $total; //数据表中总记录数 private $lis ...

  7. FPGA千兆位收发器选择指南

    选择合适的千兆位收发器(GT)是通信和实时处理领域尤其需要重点考虑的设计事项,但特定的市场领域可能会存在太多的标准.协议或使用模型.有时针对某一种应用就会涉及到好几种标准,为了选择最适合的千兆位收发器 ...

  8. Scrum Meeting NO.1

    Scrum Meeting No.1 1.会议内容 不出所料地,组员们都在忙着写编译.编译大作业的进度已经接近尾声,码农们已经磨刀霍霍向软工-- 在上一周,bugphobia和我们组决定共同使用一套后 ...

  9. 四则运算app总结

    程序有难度和单项练习,但设计了每次只出5到题,如果做错的话会把错题加入到数据库中,然后通多错题巩固选项可以对错题进行训练. 代码: 普通选项代码: package com.example.szys; ...

  10. 学习电脑编码utf-8,ansi编码的基础知识等

    大学时期就很好奇,我们所看到的文字在电脑里面是怎么记忆的,感觉不可能是文字本身,今天刚好学习java的io流知识,顺便补充了一下电脑编码知识,先看一下下面小王和小张的例子,然后思考电脑怎么存放文字?  ...