bzoj 5252: [2018多省省队联测]林克卡特树
Description
小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战。
游戏中有一个叫做“LCT” 的挑战,它的规则是这样子的:现在有一个N 个点的 树(Tree),每条边有一个整数边权vi ,若vi >= 0,表示走这条边会获得vi 的收益;若vi < 0 ,则表示走这条边需要支付- vi 的过路费。小L 需要控制主角Link 切掉(Cut)树上的 恰好K 条边,然后再连接 K 条边权为 0 的边,得到一棵新的树。接着,他会选择树上的两个点p; q ,并沿着树上连接这两点的简单路径从p 走到q ,并为经过的每条边支付过路费/ 获取相应收益。
海拉鲁大陆之神TemporaryDO 想考验一下Link。他告诉Link,如果Link 能切掉 合适的边、选择合适的路径从而使 总收益 - 总过路费最大化的话,就把传说中的大师之剑送给他。
小 L 想得到大师之剑,于是他找到了你来帮忙,请你告诉他,Link 能得到的 总收益 - 总过路费最大是多少。
Solution
凸优化
发现斜率是递增的,虽然后面可能会变成负的,二分这个斜率 \(mid\)
然后相当于选择若干条点不相交的路径,每一次选择的代价为 \(mid\),求 \((K,f(K))\) 的值
我们二分到 \((K,f(K))\) 所在直线的斜率就可以推出这个点的值
求函数的最大值和 \(60\) 分 \(DP\) 一样,设 \(f[x][0/1/2]\) 表示这个点的度数为 \(0/1/2\) 时的最大值
转移时顺便维护选择的路径数量,具体转移见代码
#include<bits/stdc++.h>
using namespace std;
template<class T>void gi(T &x){
	int f;char c;
	for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
	for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
}
typedef long long ll;
const int N=3e5+10;const ll inf=1e15;
int n,K,head[N],nxt[N*2],to[N*2],num=0,dis[N*2];ll reb,mid;
inline void link(int x,int y,int z){
	nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;
	nxt[++num]=head[y];to[num]=x;head[y]=num;dis[num]=z;
}
struct data{int x;ll y;}f[N][3];
inline bool operator <(const data &p,const data &q){
	return p.y!=q.y?p.y<q.y:p.x>q.x;
}
inline data operator +(const data &p,const data &q){
	return (data){p.x+q.x,p.y+q.y};
}
inline data operator +(const data &p,const ll q){return (data){p.x,p.y+q};}
inline void upd(data &a,data b,int c){b.x+=c;a=max(a,b);}
inline void dfs(int x,int last){
	f[x][0]=(data){0,0};f[x][1]=(data){1,-mid};f[x][2]=(data){0,-inf};
	for(int i=head[x],u;i;i=nxt[i]){
		if((u=to[i])==last)continue;
		dfs(u,x);
		data w=max(f[u][0],max(f[u][1],f[u][2]));
		upd(f[x][2],f[x][2]+w,0);
		upd(f[x][2],f[x][1]+f[u][1]+mid+dis[i],-1);
		upd(f[x][1],f[x][1]+w,0);
		upd(f[x][1],f[x][0]+f[u][1]+dis[i],0);
		upd(f[x][0],f[x][0]+w,0);
	}
}
inline int solve(){
	dfs(1,1);
	data ans=(data){0,-inf};
	for(int i=1;i<=n;i++)ans=max(ans,max(f[i][0],max(f[i][1],f[i][2])));
	if(ans.x<=K)reb=ans.y;
	return ans.x;
}
int main(){
  freopen("pp.in","r",stdin);
  freopen("pp.out","w",stdout);
  int x,y,z;
  ll l=0,r=0,ret=0;
  cin>>n>>K;K++;
  for(int i=1;i<n;i++){
	  gi(x);gi(y);gi(z);
	  link(x,y,z);l-=abs(z);r+=abs(z);
  }
  while(l<=r){
	  mid=(l+r)>>1;
	  if(solve()<=K)ret=mid,r=mid-1;
	  else l=mid+1;
  }
  reb+=ret*K;
  cout<<reb<<endl;
  return 0;
}
bzoj 5252: [2018多省省队联测]林克卡特树的更多相关文章
- bzoj5252 [2018多省省队联测]林克卡特树
		斜率优化树形dp?? 我们先将问题转化成在树上选K+1条互不相交路径,使其权值和最大. 然后我们考虑60分的dp,直接维护每个点子树内选了几条路径,然后该点和0/1/2条路径相连 然后我们会发现最后的 ... 
- bzoj 5249 [2018多省省队联测] IIIDX
		bzoj 5249 [2018多省省队联测] IIIDX Link Solution 首先想到贪心,直接按照从大到小的顺序在后序遍历上一个个填 但是这样会有大问题,就是有相同的数的时候,会使答案不优 ... 
- bzoj 5248: [2018多省省队联测]一双木棋
		Description 菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手.棋局开始时,棋盘上没有任何棋子, 两人轮流在格子上落子,直到填满棋盘时结束.落子的规则是:一个格子可以落子 ... 
- bzoj 5251: [2018多省省队联测]劈配
		Description 一年一度的综艺节目<中国新代码>又开始了. Zayid从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 题目描述 轻车熟路的Zayi ... 
- BZOJ 5249: [2018多省省队联测]IIIDX(贪心 + 线段树)
		题意 这一天,\(\mathrm{Konano}\) 接到了一个任务,他需要给正在制作中的游戏 \(\mathrm{<IIIDX>}\) 安排曲目 的解锁顺序.游戏内共有\(n\) 首曲目 ... 
- BZOJ 5248: [2018多省省队联测]一双木棋(对抗搜索)
		Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 439 Solved: 379[Submit][Status][Discuss] Descriptio ... 
- 【刷题】BZOJ 5249 [2018多省省队联测]IIIDX
		Description [题目背景] Osu听过没?那是Konano最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏.现在,他在世界知名游戏公司KONMAI内工作,离他的梦想也 ... 
- 【刷题】BZOJ 5248 [2018多省省队联测]一双木棋
		Description 菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手.棋局开始时,棋盘上没有任何棋子, 两人轮流在格子上落子,直到填满棋盘时结束.落子的规则是:一个格子可以落子 ... 
- BZOJ5249: [2018多省省队联测]IIIDX(线段树 贪心)
		题意 题目链接 Sol 不难发现题目给出的是一个树,其中\(\frac{i}{K}\)是\(i\)的父亲节点 首先,当\(d_i\)互不相同时,一个显然的贪心策略就是优先给编号小的分配较大的权值.可以 ... 
随机推荐
- webservice 创建及调用
			1.创建一个空白项目 2.在此项目上新建项--添加一个web服务 (.asmx) 这样就创建好了一个webservice --------------------------------------- ... 
- C语言编程学习:写的秒速计算四则混合运算项目
			C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ... 
- kvm虚拟机静态迁移
			1.静态迁移就是虚拟机在关机状态下,拷贝虚拟机虚拟磁盘文件与配置文件到目标虚拟主机中,实现的迁移. (1)虚拟主机各自使用本地存储存放虚拟机磁盘文件 本文实现基于本地磁盘存储虚拟机磁盘文件的迁移方式, ... 
- 发布 Android Library 到 JCenter 从入门到放弃
			最近想倒腾一个小小的 UIKit 到 JCenter,为开源社区贡献一点绵薄之力,于是就有了一系列惨无人道的踩坑史.好,接下来,直奔主题,以下是发布流程. 发布到 JCenter 发布到 JCente ... 
- SecureCRT上传下载文件
			这篇内容在哪看到的我也找不到了,不过就是做个记录. 步骤如下: 1.SecureCRT连接远程终端. 2.在连接窗口上方右击,弹出菜单后点击Connect SFTP Session, 3.点击后弹出窗 ... 
- 二叉搜索树 思想 JAVA实现
			二叉搜索树:一棵二叉搜索树是以一棵二叉树来组织的,这样一棵树可以使用链表的数据结构来表示(也可以采用数组来实现).除了key和可能带有的其他数据外,每个节点还包含Left,Right,Parent,它 ... 
- 如何高度自定义CollectionView的header和foot
			最近在研究CollectionView,突然发现觉得他的HeaderSection和FootSection也可以高度自定义. 国外有详细的教程:http://www.appcoda.com/ios-c ... 
- 日志一直打印 DEBUG o.s.amqp.rabbit.listener.BlockingQueueConsumer
			<?xml version="1.0" encoding="UTF-8"?> <configuration> <logger na ... 
- ios真机测试问题
			前端页面在ios端真机测试出现的问题 由于苹果对于性能的要求是近乎苛刻,如果没有可点的特性的元素系统默认不会给它响应事件,因此真机测试时容易添加不上绑定事件 解决办法: 1.通过js判断当前是否为苹果 ... 
- 【Python】端口扫描脚本
			0x00 使用模块简介 1.optparse模块 选项分析器,可用来生成脚本使用说明文档,基本使用如下: import optparse #程序使用说明 usage="%prog -H ... 
