1. 程式人生 > >bzoj5252 [2018多省省隊聯測]林克卡特樹

bzoj5252 [2018多省省隊聯測]林克卡特樹

相交 close play define nbsp namespace OS display code

斜率優化樹形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

bzoj5252 [2018多省省隊聯測]林克卡特樹