转载请注明出处:http://www.cnblogs.com/TSHugh/p/8776179.html

先说60分的.
思路题解上很清晰:

问题似乎等价于选K+1条点不相交的链哎!
F(x,k,0/1/2)表示考虑以x为根的子树,选了k条链,点x的度数为0/1/2的最优解.

我说一下比较坑的地方吧:
1.初始化要-Inf(反正我不加这个会wa)
2.注意转移的顺序
3.别忘了突然出现新的路径或者突然消失了一个路径的时侯加减1
4.一定要割k下
细节说多不多,说少不少,还得自己打.
说一下100分的.
60分的瓶颈在于k,那么如果对于k没有限制的话,那么我们的转移就会变成O(n)的(和60分的dp是差不多的).
如何去掉k的限制呢,我们考虑,我们的答案数组关于下标是凸包(想一下就会发现很显然啊).那么我们想到凸包就会想卡他,那么也就是我们设斜率去卡到k,那么我们有了斜率会发生什么呢.
我们的问题转化为了——设斜率为cost,那么就是求,这棵树选取若干条不相交路径,得到的贡献是路径边权和,代价是每条路径花费cost,求最终答案(最大化收益),及其路径条数.
这样我们每次二分出斜率之后会O(n)出解,得到路径条数,从而继续二分.
不难打,有了60分的dp之后,给到二分斜率的思路就应该可以写出来了.

(补充一下:这玩意似乎是wqs二分……)

#include <cstdio>
#include <cstring>
#include <algorithm>
char xB[(<<)+],*xS,*xT;
#define gtc() (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++)
inline void read(int &x){
register char ch=gtc();
bool ud=false;
for(x=;ch<''||ch>'';ch=gtc())
if(ch=='-')
ud=true;
for(;ch>=''&&ch<='';ch=gtc())
x=x*+ch-'';
if(ud)x=-x;
}
typedef long long LL;
const int N=;
const LL Inf=1e15;
struct V{
int to,next,w;
}c[N<<];
int head[N],t;
inline void add(int x,int y,int z){
c[++t].to=y,c[t].next=head[x],head[x]=t,c[t].w=z;
}
int n;
LL k;
struct A{
int x;LL y;
inline void reset(){x=,y=;}
inline void set(){x=,y=-Inf;}
inline A up(){
A ret=*this;
++ret.x,ret.y-=k;
return ret;
}
inline void cover(A a){
if(a.y>y||(a.y==y&&a.x<x))
(*this)=a;
}
inline void cover(A a,A b){
if(a.y==-Inf||b.y==-Inf)return;
a.x+=b.x,a.y+=b.y;
cover(a);
}
inline void cover(A a,A b,LL w,int opt){
if(a.y==-Inf||b.y==-Inf)return;
a.x+=b.x-opt,a.y+=b.y+w+(opt?k:);
if(a.x<=)return;
cover(a);
}
}f[N][];
inline void dfs(int x,int fa){
int i,v;
f[x][].reset();
f[x][].set();
f[x][].set();
for(i=head[x];i;i=c[i].next){
v=c[i].to;
if(v==fa)continue;
dfs(v,x);
f[x][].cover(f[x][],f[v][]);
f[x][].cover(f[x][],f[v][],c[i].w,);
f[x][].cover(f[x][],f[v][]);
f[x][].cover(f[x][],f[v][],c[i].w,);
f[x][].cover(f[x][],f[v][]);
}
f[x][].cover(f[x][].up());
f[x][].cover(f[x][]);
f[x][].cover(f[x][]);
}
inline A solve(){
dfs(,);
return f[][];
}
int main(){
int need;
read(n),read(need);
++need;
int i,x,y,z;
for(i=;i<n;++i){
read(x),read(y),read(z);
add(x,y,z),add(y,x,z);
}
LL l=-1e12,r=1e12,mid,ans=;
A ret;
while(l<=r){
k=mid=l+r>>;
ret=solve();
if(ret.x<=need)
ans=ret.y+need*k,r=mid-;
else
l=mid+;
}
printf("%lld\n",ans);
return ;
}

Kod

【HEOI 2018】林克卡特树的更多相关文章

  1. [八省联考2018]林克卡特树lct——WQS二分

    [八省联考2018]林克卡特树lct 一看这种题就不是lct... 除了直径好拿分,别的都难做. 所以必须转化 突破口在于:连“0”边 对于k=0,我们求直径 k=1,对于(p,q)一定是从p出发,走 ...

  2. [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树

    [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树 题意 给定一个 \(n\) 个点边带权的无根树, 要求切断其中恰好 \(k\) 条边再连 \(k\) 条边权为 \(0\) ...

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

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

  4. luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分)

    luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分) Luogu 题解时间 $ k $ 条边权为 $ 0 $ 的边. 是的,边权为零. 转化成选正好 $ k+1 $ 条链. $ ...

  5. P4383 [八省联考2018]林克卡特树 树形dp Wqs二分

    LINK:林克卡特树 作为树形dp 这道题已经属于不容易的级别了. 套上了Wqs二分 (反而更简单了 大雾 容易想到还是对树进行联通情况的dp 然后最后结果总和为各个联通块内的直径. \(f_{i,j ...

  6. BZOJ5252 八省联考2018林克卡特树(动态规划+wqs二分)

    假设已经linkcut完了树,答案显然是树的直径.那么考虑这条直径在原树中是怎样的.容易想到其是由原树中恰好k+1条点不相交的链(包括单个点)拼接而成的.因为这样的链显然可以通过linkcut拼接起来 ...

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

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

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

    题目链接 题意分析 一句话题意就是 : 让你选出\((k+1)\)条不相交的链 使得这些链的边权总和最大 (这些链可以是点) 我们考虑使用树形\(DP\) \(dp[i][j][0/1/2]\)表示以 ...

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

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

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

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

随机推荐

  1. python练习---小脚本

    一.爬子域名 #!/usr/bin/python # -*- coding: utf-8 -*- import requests import re import sys def get(domain ...

  2. 【转】glumer Appium + Python环境搭建(移动端自动化)

    最近整理了一下自动化的东西,好久没搭建环境又踩了不少坑,appium的环境搭建比较繁琐,好多同行估计都在环境上被卡死了.分享一下~~ 一.安装JDK,配置JDK环境    百度搜索下载就行,这里分享一 ...

  3. Python接口测试实战3(下)- unittest测试框架

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  4. K-近邻算法入门

    K-近邻算法的直观理解就是:给定一个训练集合,对于新的实例,在训练集合中找到k个与该实例最近的邻居,然后根据“少数服从多数”原则判断该实例归属于哪一类,又称“随大流” K-近邻算法的三大要素:K值得选 ...

  5. 算法笔记(c++)--求一个数的所有质数因子

    算法笔记(c++)--求一个数的所有质数因子 先贴题目: 这题不难,恶心在理解上面.最后看评论知道了怎么回事: 2*2*3*3*5=180 按照这逻辑的话应该输入的数由一系列质数相乘出来,所以每次找到 ...

  6. FivePlus——团队展示

    光耀101  <光耀101>是福州大学数计学院计算机专业推出的中国首部程序猿脱发养成节目.由张栋担任发起人,刘晨瑶.畅畅担任导师.  该节目召集了你猜多少位选手,通过任务.训练.考核,让选 ...

  7. 事后诸葛亮--Alpha版本总结

    目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结: 本小组和其他组的评分 分工和贡献分 全组讨论的照片 问题 第一组提问回答:爸爸饿了队 第二组提问回答:拖 ...

  8. 未能加载文件或程序集“log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821”或它的某一个依赖项。系统找不到指定的文件。

    在网上找了很久,很多个地方让修改配置文件,也有重装log4net的. 如文章:使用Common.Logging与log4net的组件版本兼容问题 我检查下发现项目中的package包中的Log4net ...

  9. lintcode-507-摆动排序 II

    507-摆动排序 II 给你一个数组nums,将它重排列如下形式 nums[0] < nums[1] > nums[2] < nums[3].... 注意事项 你可以认为每个输入都有 ...

  10. Iterable,Iterator和forEach

    Iterable Interface Iterable<T> 方法: Iterator<T> iterator() Returns an iterator over a set ...