【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 那道题, ...
随机推荐
- 安装Vue.js的方法有三种
1 使用独立的版本 在Vue.js官网上直接下载,在script标签里引用. 2 使用CND方法(不推荐) 3 NMP 方法 在用Vue.js构建大型应用的时候推荐使用NMP安装方法,NMP能很好的和 ...
- php oci8 小试
Oracle_db.class.php <?phpclass Oracle_db{ public $link; public function __construct(){ ...
- Phaser3让超级玛丽实现轻跳、高跳及加上对应的跳跃声音
mario jumper 在线测试地址:http://www.ifiero.com/uploads/phaserjs3/jumper/ 空格键:轻按:跳低 ,长按:跳高键盘:--> 向右 , ...
- Java如何调用shell脚本的
有些时候会碰到这样的场景:java的功能里面要嵌入一个功能点,这个功能是通过是shell脚本实现的.这种时候就需要Java对脚本调用的支持了. 测试环境 Ubuntu16.04 i3-6100,12G ...
- LVM缩小根分区
逻辑卷不是根分区都可以在线扩容和缩小 根分区是可以在线扩容,但不可以在线缩小 Linux系统进入救援模式 依次选择: 欢迎界面 ---------- Rescue installed system C ...
- Kafka安装之三 spring-kafka实践
一.spring-kafka配置详解 1.1 要是用spring-kafka 我们首先要在pom要.xml中引入spring-kafka包 <dependencies> <depen ...
- [T-ARA][HOLIDAY]
歌词来源:http://music.163.com/#/song?id=22704407 HOLI HOLI DAY [HOLI HOLI DAY] 뚜뚜 뚜루루 [ddu-ddu ddu-lu-lu ...
- arcgis10.2怎么把地理坐标系转化为投影坐标系(平面,米制坐标) arcmap 10.2 从 WGS_1984 转 Beijing_1954
方法一:在Arcmap中转换:从 WGS_1984 转 Beijing_19541.加载要转换的数据,右下角为经纬度2.点击视图——数据框属性——坐标系统3.导入或选择正确的坐标系(如选:Beijin ...
- JS 操作 checkbox(cc角色管理等)
1.获取选中的权限的个数 var size=$("input[name='privileges']:checked").size();
- c# 读取blob数据
Stream stream = new MemoryStream(data); BinaryReader r = new BinaryReader(stream); int iRawImageWidt ...