BZOJ5252 林克卡特樹(動態規劃,凸優化)

2021-08-22 08:16:11 字數 1634 閱讀 6849

bzoj(交不了)

洛谷這個東西顯然是隨著斷開的越來越多,收益增長速度漸漸放慢。

所以可以凸優化。

考慮乙個和

k k

相關的dp

' role="presentation">dpd

p這個題目可以轉換為在樹上選擇

k k

條不相交的路徑。 設f

[i][

0/1/

2]' role="presentation">f[i

][0/

1/2]

f[i]

[0/1

/2]表示當前點

i i

,這個點不和父親連/和父親連/在這裡將兩條鏈合併的最優值。

再記一維

k' role="presentation">k

k,表示子樹中已經選了

k k

條鏈。

這樣子可以直接轉移。

那麼凸優化dp

' role="presentation">dpd

p,再額外記錄一下最優解的鏈的最小值,就好了。

#include

#include

#include

#include

#include

#include

using

namespace

std;

#define ll long long

#define max 300300

inline

int read()

struct linee[max<<1];

int h[max],cnt=1;

inline

void add(int u,int v,int w);h[u]=cnt++;}

ll sum;

int n,k;

struct nodef[3][max],ans;

bool

operator

<(node a,node b)

node operator+(node a,node b);}

void cmax(node &a,node b);

f[1][u]=(node);

f[2][u]=(node);

for(int i=h[u];i;i=e[i].next)

);cmax(f[1][u],f[1][u]+tmp);

cmax(f[1][u],f[0][u]+f[1][v]+(node));

cmax(f[1][u],f[0][u]+f[0][v]+(node));

cmax(f[0][u],f[0][u]+tmp);

}cmax(ans,max(f[0][u],max(f[1][u],f[2][u])));

}int main()

ll l=-sum,r=sum;

while(l>1;

ans=(node);dfs(1,0,mid);

if(ans.y>k)l=mid+1;

else r=mid;

}ans=(node);dfs(1,0,r);

printf("%lld\n",r*k+ans.x);

return

0;}

loj2478林克卡特樹

聽說這題要用到乙個叫做 帶權二分 的黑科技 名稱來自於apio2018講課課件 那就讓我來體驗一下。寫了一發,感覺概念還好懂,但特別容易掛。有幾個要點 1.要對輸入資料加以隨機擾動,不然會被三點共線的資料卡。2.如果上次答案和這次答案的差很小,則直接輸出這次答案,不然會被卡精度。3.其實可以把權值和...

HEOI 2018 林克卡特樹

先說60分的.思路題解上很清晰 問題似乎等價於選k 1條點不相交的鏈哎 f x,k,0 1 2 表示考慮以x為根的子樹,選了k條鏈,點x的度數為0 1 2的最優解.我說一下比較坑的地方吧 1.初始化要 inf 反正我不加這個會wa 2.注意轉移的順序 3.別忘了突然出現新的路徑或者突然消失了乙個路徑...

2018八省聯考 林克卡特樹

題目真滴皮 orz rqy 10分的暴力都沒拿到 10分直接求直徑 60分 容易?想到題目等價於求k 1條不相交的鏈 設狀態f i j 0 1 2 f i j 0 1 2 表示以第i個節點為根的子樹用了j條鏈並且根和兒子連有 0,1,2 條邊。轉移分為5類 g j cc 0 max g j cc 0...