bzoj5252 [2018多省省队联测]林克卡特树

斜率优化树形dp??

我们先将问题转化成在树上选K+1条互不相交路径,使其权值和最大。

然后我们考虑60分的dp,直接维护每个点子树内选了几条路径,然后该点和0/1/2条路径相连

然后我们会发现最后的答案关于割的边数是一个单峰的函数,这时候事情就变得明朗起来个p

我们考虑拿一条斜率为k的直线去切这个函数,切到的点是什么?是每选一条路径额外付出k点代价时的最优解,于是我们二分这个斜率,然后直接树形dp求最优解以及位置即可,因为每次的最优解一定是上次的最优解和儿子的最优解共同转移而来的,所以我们只需要对每个度数维护最优解和位置即可。然后我们就可以根据dp出的位置调整斜率,然后找到答案。

这不就是wqs二分吗。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #define N 300500
 7 #define pr pair<long long,int>
 8 #define mk make_pair
 9 #define fir first
10 #define sec second
11 #define inf 0x7fffffffffffffff
12 using namespace std;
13 int e=1,head[N];
14 struct edge{
15     int v,w,next;
16 }ed[N<<1];
17 void add(int u,int v,int w){
18     ed[e].v=v;ed[e].w=w;
19     ed[e].next=head[u];head[u]=e++;
20 }
21 int n,m,K;
22 long long ans;
23 pr f[N][3],g[3],mx;
24 void add(pr &a,pr b){if(b.fir>a.fir||(b.fir==a.fir&&b.sec<a.sec))a=b;}
25 void dfs(int x,int fa){
26     f[x][0]=mk(0,0);f[x][1]=mk(-m,1);f[x][2]=mk(-inf,0);
27     for(int i=head[x];i;i=ed[i].next){
28         int v=ed[i].v;
29         if(v==fa)continue;
30         dfs(v,x);
31         g[0]=f[x][0];g[1]=f[x][1];g[2]=f[x][2];
32         mx=f[v][0];add(mx,f[v][1]);add(mx,f[v][2]);
33         add(f[x][0],mk(g[0].fir+mx.fir,g[0].sec+mx.sec));
34         add(f[x][1],mk(g[1].fir+mx.fir,g[1].sec+mx.sec));
35         add(f[x][1],mk(g[0].fir+f[v][1].fir+ed[i].w,g[0].sec+f[v][1].sec));
36         add(f[x][2],mk(g[2].fir+mx.fir,g[2].sec+mx.sec));
37         add(f[x][2],mk(g[1].fir+f[v][1].fir+ed[i].w+m,g[1].sec+f[v][1].sec-1));
38     }
39 }
40 int main(){
41     scanf("%d%d",&n,&K);
42     for(int i=1,u,v,w;i<n;i++){
43         scanf("%d%d%d",&u,&v,&w);
44         add(u,v,w);add(v,u,w);
45     }
46     int l=-1000000000,r=1000000000,mid,fin;
47     while(l<=r){
48         m=mid=(l+r)>>1;
49         dfs(1,0);
50         mx=f[1][0];add(mx,f[1][1]);add(mx,f[1][2]);
51         if(mx.sec<=K+1)fin=mid,r=mid-1;
52         else l=mid+1;
53     }
54     m=fin;
55     dfs(1,0);
56     mx=f[1][0];add(mx,f[1][1]);add(mx,f[1][2]);
57     ans=mx.fir+1ll*(K+1)*m;
58     printf("%lld\n",ans);
59     return 0;
60 }
View Code

 

转载于:https://www.cnblogs.com/Ren-Ivan/p/8782360.html

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值