林克卡特树

题解

挺简单的一道题。

原题断 k k k条边连 k k k条边权为 0 0 0的边相当于寻去 k + 1 k+1 k+1条不相交链出来,将它们连上得到的结果。
所以我们要从原树中选取 k + 1 k+1 k+1条链出来,使得它们的权值和最大。

我们发现恰好 k + 1 k+1 k+1条链这个限制是比较难限制的,考虑通过凸优化二分去进行维护。
由于链选取的条数关于贡献的函数一定是一个凸包,我们可以去二分通过选取 k k k条链的点的切线的斜率,来进行判断。
我们将每条路径的贡献减去当前的二分值,再直接用二分去选取不限量的路径,使得权值最大。
dp出来的选取链数大于 k k k,则说明我们当前二分的值大了,否则就说明小了,只有当选取刚好 k k k条路径时才能说明我们二分的值是恰当的。

关于这个dp,就是个简单的树dp,在树上找链,相信大家都会。

总时间复杂度 O ( n l o g n ) O\left(nlog\,n\right) O(nlogn)。

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
#define MAXN 300005
#define lowbit(x) (x&-x)
#define reg register
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
const LL INF=0x7f7f7f7f7f7f;
const int mo=1e9+7;
const double PI=acos(-1.0);
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
int n,k,head[MAXN],tot;LL dif;
struct edge{int to,nxt;LL paid;}e[MAXN<<1];
void addEdge(int u,int v,LL w){e[++tot]=(edge){v,head[u],w};head[u]=tot;}
struct ming{LL sum;int num;friend ming operator + (const ming &x,const ming &y){return (ming){x.sum+y.sum,x.num+y.num};}friend bool operator < (const ming &x,const ming &y){if(x.sum==y.sum)return x.num<y.num;return x.sum<y.sum;}
}dp[MAXN][3];
ming Max(ming x,ming y){return x<y?y:x;}
void dosaka(int u,int fa){for(int i=head[u];i;i=e[i].nxt){int v=e[i].to;if(v==fa)continue;dosaka(v,u);dp[u][2]=Max(dp[u][2]+dp[v][0],dp[u][1]+dp[v][1]+(ming){e[i].paid-dif,1});dp[u][1]=Max(dp[u][1]+dp[v][0],dp[u][0]+dp[v][1]+(ming){e[i].paid,0});dp[u][0]=dp[u][0]+dp[v][0];}dp[u][0]=Max(dp[u][0],Max(dp[u][2],dp[u][1]+(ming){-dif,1}));
}
LL sakura(const LL mid){    for(int i=1;i<=n;i++)dp[i][0]=dp[i][1]=(ming){0,0},dp[i][2]=(ming){-mid,1};dif=mid;dosaka(1,0);return dp[1][0].num;
}
signed main(){read(n);read(k);LL sum=0;for(int i=1;i<n;i++){int u,v;LL w;read(u);read(v);read(w);addEdge(u,v,w);addEdge(v,u,w);sum+=Fabs(w);}LL l=-sum,r=sum;while(l<r){LL mid=l+r+1>>1;if(sakura(mid)>=k+1)l=mid;else r=mid-1;}LL tmp=sakura(l);printf("%lld",dp[1][0].sum+1ll*(k+1)*l);return 0;
}

谢谢!!!

[八省联考2018]林克卡特树相关推荐

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

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

  2. luogu4383 bzoj5252[八省联考2018]林克卡特树lct

    ** [八省联考2018]林克卡特树lct** luogu bzoj 分析 很神仙的一道wqs二分.是真的不会切>-< 如果已经切完了,最优秀的方案就是每个联通块搞直径然后连起来一定是最优 ...

  3. P4383 [八省联考2018]林克卡特树(树形dp+wqs二分)

    [八省联考2018]林克卡特树 题目大意:给定一棵有负权边的树,现在必须恰好删去 k k k条边,并加上恰好 k k k条权值为 0 0 0的边,要求最大化它的直径长度. 首先考虑删去 K K K条边 ...

  4. 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)

    题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做"LC ...

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

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

  6. P4383 [八省联考 2018] 林克卡特树(wqs二分、树形dp)

    解析 它还真的不难. 乐. 这题没做出来有些谔谔. 外层wqs二分显而易见,里面不知道为啥我总觉得这个题可以贪心. 然后一直试图在原树直径上下功夫,一筹莫展. 看到题解"dp"两个 ...

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

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

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

    题面在这里 description 一个\(N\)个点的\(Tree\),每条边有一个整数边权\(v_i\),表示走这条边会获得\(v_i\)的收益: 小\(L\)需要控制主角\(Link\),\(C ...

  9. 解题:八省联考2018 林克卡特树

    题面 DP凸优化 题目并不难 先转化问题,显然k=0的时候我们都知道是求直径,然后k=1就是选两条点不相交的链拼起来,很容易推出题目就是要我们在树上选$k+1$条点不相交的链 事实上你直接按照边不相交 ...

最新文章

  1. 程序、进程、线程的关系
  2. CUDA ---- device管理
  3. jmeter测试元件--控制器
  4. docker 配置nginx镜像出现 403 Forbidden的问题
  5. BugkuCTF-WEB题login1
  6. SpringBoot—整合log4j2入门和log4j2.xml配置详解
  7. LCN根据官网改造本项目失败案例
  8. 2021 王道考研 计算机组成原理+习题讲解
  9. jxl生成excel 设置隐藏列 隐藏行
  10. openssl 实现 aes 文件加密解密
  11. 窄带物联网应用于工业计算机,工业物联网嵌入式边缘计算机的制作方法
  12. android系统版本卸掉,使用内置软件卸载最新版本的Android
  13. 网站流量统计指标分为三大类
  14. 【error】_smartbi数据集超出最大行数: DataRows > 1000
  15. 软件测试投递简历找工作总是已读不回怎么办?
  16. 磁盘数据泄密威胁和销毁技术
  17. 名字中间一条线怎么弄_如何在QQ昵称上加一条横线
  18. 新版本如何给微信小程序配置vant-weapp
  19. 学习软件是否一定要去培训学院
  20. Kibana:如何开始使用 Kibana

热门文章

  1. 退出python交互模式_暂时退网的说说 开学退网个性说说
  2. 孕期分别是哪些事项呢?各个时期要注意的事项不同
  3. C++【对象模型】 | 【05】类与类之间各种关系下对数据成员的存取、绑定、布局
  4. 拯救redis被攻击后的服务器
  5. Linux中用C语言写系统日志
  6. 【每日早报】2019/07/26
  7. kettle数据溢出了怎么办_KETTLE内存溢出解决方案
  8. IDEA设置提示菜单的快捷键【解决快捷键冲突】
  9. 【1.12】件件有着落 事事有回音 万事皆有原因
  10. 基于FPGA的DDS在Vivado中仿真以及在ZYNQ7020上板的实现(1)