题意

给出一棵n个节点的树和k,边有边权,要求先从树中选k条边,然后把这k条边删掉,再加入k条边权为0的边,满足操作完后的图仍然是一棵树。问新树的带权直径最大是多少。
n,k≤3∗105n,k≤3∗105n,k\le3*10^5

分析

不难发现我们要求的就是在树中选出k+1条不相交的链使得其权值和最大。
当k比较小的时候,我们可以树形dp,设f[i,j,0/1/2]f[i,j,0/1/2]f[i,j,0/1/2]表示以i为根的树中选了j条链,节点i的度数为0/1/20/1/20/1/2时的最大权值。
这样做的复杂度是O(nk)O(nk)O(nk)的。
当k变大之后,我们就可以用带权二分来做。
具体来说就是二分一个权值midmidmid,然后给每条路径的权值加上midmidmid,再去除k的限制后进行dp。若选出的链的数量不小于k+1,则把mid减小,否则把mid增大。
当某一刻选出的链数量恰好为k+1,则当前权值-mid*(k+1)就是答案了。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>typedef long long LL;const int N=300005;
const LL inf=(LL)1e12;int n,k,cnt,last[N];
LL mid;
struct data
{LL x,y;bool operator > (const data &d) const {return x>d.x||x==d.x&&y>d.y;}bool operator < (const data &d) const {return x<d.x||x==d.x&&y<d.y;}data operator + (const data &d) const {return (data){x+d.x,y+d.y};}
}f[N][3],tmp[3];
struct edge{int to,next,w;}e[N*2];int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}void addedge(int u,int v,int w)
{e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;e[++cnt].to=u;e[cnt].w=w;e[cnt].next=last[v];last[v]=cnt;
}void dp(int x,int fa)
{f[x][0]=(data){0,0};f[x][1]=(data){-inf,0};f[x][2]=(data){mid,1};for (int i=last[x];i;i=e[i].next){int to=e[i].to;if (to==fa) continue;dp(to,x);data u;tmp[0]=tmp[1]=tmp[2]=(data){-inf,0};u=f[x][0]+f[to][0];tmp[0]=std::max(tmp[0],u);u.x+=(LL)e[i].w+mid;u.y++;tmp[1]=std::max(tmp[1],u);u=f[x][0]+f[to][1];tmp[0]=std::max(tmp[0],u);u.x+=(LL)e[i].w;tmp[1]=std::max(tmp[1],u);u=f[x][0]+f[to][2];tmp[0]=std::max(tmp[0],u);u=f[x][1]+f[to][0];tmp[1]=std::max(tmp[1],u);u.x+=(LL)e[i].w;tmp[2]=std::max(tmp[1],u);u=f[x][1]+f[to][1];tmp[1]=std::max(tmp[1],u);u.x+=e[i].w-mid;u.y--;tmp[2]=std::max(tmp[2],u);u=f[x][1]+f[to][2];tmp[1]=std::max(tmp[1],u);u=f[x][2]+f[to][0];tmp[2]=std::max(tmp[2],u);u=f[x][2]+f[to][1];tmp[2]=std::max(tmp[2],u);u=f[x][2]+f[to][2];tmp[2]=std::max(tmp[2],u);f[x][0]=tmp[0];f[x][1]=tmp[1];f[x][2]=tmp[2];}
}int main()
{n=read();k=read();for (int i=1;i<n;i++){int x=read(),y=read(),z=read();addedge(x,y,z);}LL l=-inf,r=inf,ans;while (l<=r){mid=(l+r)/2;dp(1,0);data u=std::max(f[1][0],std::max(f[1][1],f[1][2]));if (u.y>=k+1) ans=u.x,r=mid-1;else l=mid+1;}printf("%lld",ans-(LL)(r+1)*(k+1));return 0;
}

LibreOJ #2478.「九省联考 2018」林克卡特树 树形dp+带权二分相关推荐

  1. @loj - 2478@「九省联考 2018」林克卡特树

    目录 @description@ @solution@ @part - 1@ @part - 2@ @accepted code@ @details@ @description@ 小 L 最近沉迷于塞 ...

  2. [loj 2478][luogu P4843]「九省联考 2018」林克卡特树

    传送门 Description 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一 ...

  3. 「九省联考 2018」一双木棋

    「九省联考 2018」一双木棋 题目描述 菲菲和牛牛在一块 \(n\) 行 \(m\) 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手. 棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满 ...

  4. 【LOJ】#2479. 「九省联考 2018」制胡窜

    题解 老了,国赛之前敲一个后缀树上LCT和线段树都休闲的很 现在后缀树上线段树合并差点把我写死 主要思路就是后缀树+线段树合并+容斥,我相信熟练的OIer看到这已经会了 但就是不想写 但是由于我过于老 ...

  5. [博弈] LOJ#2471. 「九省联考 2018」一双木棋

    考虑暴力. 每次枚举放哪个位置,设已经放了棋子的位置集合为 SSS,fS" role="presentation">fSfSf_S 表示当前放置情况为 SSS 时, ...

  6. 【九省联考2018】秘密袭击【树形dp】【生成函数】【线段树合并】【多项式插值】

    题意:nnn 个点的带点权的树,点权最大值为 www,求所有连通子图第 kkk 大权值之和模 641236412364123. n,w≤1666n,w\leq 1666n,w≤1666,时限 5s. ...

  7. BZOJ.5249.[九省联考2018]iiidx(贪心 线段树)

    BZOJ LOJ 洛谷 \(d_i\)不同就不用说了,建出树来\(DFS\)一遍. 对于\(d_i\)不同的情况: Solution 1: xxy tql! 考虑如何把这些数依次填到树里. 首先对于已 ...

  8. [九省联考2018]IIIDX 贪心 线段树

    ~~~题面~~~ 题解: 一开始翻网上题解看了好久都没看懂,感觉很多人都讲得不太详细,所以导致一些细节的地方看不懂,所以这里就写详细一点吧,如果有不对的or不懂的可以发评论在下面. 首先有一个比较明显 ...

  9. 洛谷P4364 [九省联考2018]IIIDX(线段树)

    传送门 题解看得--很--迷? 因为取完一个数后,它的子树中只能取权值小于等于它的数.我们先把权值从大到小排序,然后记$a_i$为他左边(包括自己)所有取完他还能取的数的个数.那么当取完一个点$x$的 ...

最新文章

  1. 非此即彼的逻辑错误_超全MBA逻辑答题口诀,快收藏!
  2. 【以前的空间】主席树
  3. tf.unstack\tf.unstack
  4. Rxjava、Retrofit返回json数据解析异常处理
  5. 深入理解Oracle表(5):三大表连接方式详解之Hash Join的定义,原理,算法,成本,模式和位图
  6. python开发面试问题及答案_前50个Python面试问题(最受欢迎)
  7. 分页输入框跳转 java_displaytag 分页-添加页码输入框跳转至指定页
  8. 成立出版社的条件_厦门大学出版社招聘启事
  9. python turtle画房子详细解释_简述python的turtle绘画命令及解释
  10. 机器视觉打光方案(NOMEX胶纸)
  11. apache服务上配置https安全与域名请求
  12. java common-lang_commons-lang.jar下载
  13. matlab中pwm占空比计算代码,如何计算pwm波占空比
  14. 计算机考研去航空专业,北京航空航天大学计算机专业考研方向有哪些?
  15. php如何做left,php函数substr实现asp中left和right应用
  16. sox处理mp3_sox :音频文件转换命令
  17. 解读国内外园艺机器人的应用现状
  18. 企服网:语音线路市面上有哪些?
  19. MacOS Big Sur 如何安装创新SBX-Fi Surround 5.1Pro(USB外置)声卡?
  20. PDPS软件:机器人抓手工具运动机构制作与仿真运行测试

热门文章

  1. 中国餐饮行业报告,中国传统餐厅成本结构分析,净利润占比20%
  2. 收购后Java之父首次公开亮相 称Oracle掌管Java令人放心
  3. java 印章图片_Java生成印章图片
  4. PHPMaker 2019绿色破解版
  5. CSDN富文本常用快捷键
  6. 什么是对象的深浅拷贝?怎么实现深浅拷贝?
  7. 《乱音盒子》之《I Swear》
  8. linux 管道相关命令(待学)
  9. Java netty的option(ChannelOption.SO_BACKLOG, backLog)什么意思
  10. upc 2022/2/27 校赛+洛谷6599