【HEOI 2018】林克卡特树
转载请注明出处: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】林克卡特树的更多相关文章
- [八省联考2018]林克卡特树lct——WQS二分
[八省联考2018]林克卡特树lct 一看这种题就不是lct... 除了直径好拿分,别的都难做. 所以必须转化 突破口在于:连“0”边 对于k=0,我们求直径 k=1,对于(p,q)一定是从p出发,走 ...
- [BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树
[BZOJ 5252][LOJ 2478][九省联考2018] 林克卡特树 题意 给定一个 \(n\) 个点边带权的无根树, 要求切断其中恰好 \(k\) 条边再连 \(k\) 条边权为 \(0\) ...
- LuoguP4383 [八省联考2018]林克卡特树lct
LuoguP4383 [八省联考2018]林克卡特树lct https://www.luogu.org/problemnew/show/P4383 分析: 题意等价于选择\(K\)条点不相交的链,使得 ...
- luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分)
luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分) Luogu 题解时间 $ k $ 条边权为 $ 0 $ 的边. 是的,边权为零. 转化成选正好 $ k+1 $ 条链. $ ...
- P4383 [八省联考2018]林克卡特树 树形dp Wqs二分
LINK:林克卡特树 作为树形dp 这道题已经属于不容易的级别了. 套上了Wqs二分 (反而更简单了 大雾 容易想到还是对树进行联通情况的dp 然后最后结果总和为各个联通块内的直径. \(f_{i,j ...
- BZOJ5252 八省联考2018林克卡特树(动态规划+wqs二分)
假设已经linkcut完了树,答案显然是树的直径.那么考虑这条直径在原树中是怎样的.容易想到其是由原树中恰好k+1条点不相交的链(包括单个点)拼接而成的.因为这样的链显然可以通过linkcut拼接起来 ...
- 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)
题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...
- P4383 [八省联考2018]林克卡特树lct
题目链接 题意分析 一句话题意就是 : 让你选出\((k+1)\)条不相交的链 使得这些链的边权总和最大 (这些链可以是点) 我们考虑使用树形\(DP\) \(dp[i][j][0/1/2]\)表示以 ...
- 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 那道题, ...
随机推荐
- Mac下布置appium环境
1.下载或者更新Homebrew:homebrew官网 macOS 不可或缺的套件管理器 $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githu ...
- Spine with Unity Mecanim
前言 最近这两天刚刚接触Spine,研究了一下Unity Mecanim Animator如何控制Spine,在此分享记录一下,如有不当之处,请留言指出,欢迎讨论. Unity & Spine ...
- Delphi 实现照片抽奖-原创
有单位年会要用照片抽奖,上网搜了几个都不满意,且居然还要收费.自己写一个算了.只是有一点不爽,Delphi 7 在 Windows 7 64位下有问题,不能双击 dpr 文件直接打开项目! 关于性能: ...
- k8s zookeeper、kafka部署
安装zookeeper apiVersion: v1 kind: ConfigMap metadata: name: zookeeper-config namespace: kube-system a ...
- A Product Recall 产品召回
Rick: The Board of Directors has come to a decision. Our company will take an image hit, and it's go ...
- Python爬虫入门(6):Cookie的使用
为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓 ...
- oracle时间转换查询
查询oracle 数据库时要查询某一字段的最大时间或者最小时间,因为oracle的时间点 精确到毫秒 甚至更高精度级别 根据字段来转换成对应的时间格式: SELECT TO_CHAR(MAX(crea ...
- Karen and Coffee CF 816B(前缀和)
Description To stay woke and attentive(专注的) during classes, Karen needs some coffee! Karen, a coffee ...
- python knn自我实践
#得到分类数据和测试数据 import pymysql import struct from numpy import * a=['']*20 #存图像 分类数据 b=[[0]*76800]*20#存 ...
- DCOM初步窥探二
1.COM进程透明性表现在“组件对象和客户程序可以拥有各自的空间,也可以共享同一个进程空间”. COM负责把客户的调用正确传到组件对象中,并保证参数传递的正确性. 组件对象和客户代码不必考虑调用传递的 ...