1. 程式人生 > >[2018八省聯考] 林克卡特樹

[2018八省聯考] 林克卡特樹

題目真滴皮
Orz rqy

思路

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

g[j+cc][0]=max(g[j+cc][0],f[x][j][0]+max(f[v][cc][0],max(f[v][cc][1],f[v][cc][2])));
if(cc) g[j+cc][1]=max(g[j+cc][1],f[x][j][0]+f[v][cc][1]+tb[i].w);
if(j) g[j+cc
][1]=max(g[j+cc][1],f[x][j][1]+max(f[v][cc][0],max(f[v][cc][1],f[v][cc][2]))); if(j) g[j+cc][2]=max(g[j+cc][2],f[x][j][2]+max(f[v][cc][0],max(f[v][cc][1],f[v][cc][2]))); if(j && cc) g[j+cc-1][2]=max(g[j+cc-1][2],f[x][j][1]+f[v][cc][1]+tb[i].w);

100分正解 好像是叫wqs二分的東東。
如果不考慮k的話可以省掉一維讓時間複雜度達到O

(n)
f[i][0/1/2]表示以i為根的子樹 balabala
經過一番推導打表驗證 f是一個凸函式
他的差分陣列單調遞減。 可以dp求得最大值和鏈的個數和k比較一下。
顯然如果對於差分陣列整體減一個數的話最大值點是會左移的那麼就可以二分這個減去的數啦。
設減去的數為 s
怎麼減去整個數呢?
g[i]表示i條鏈的答案 那麼設h[i]=g[i]is h的差分陣列就可以讓每一個減去s了
上下界l,r。 r=所有正權值和,l=最大正權邊的相反數。
分別對應著差分陣列的兩極。

程式碼

//林可卡特樹  wqs二分 
#include <iostream>
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #include <climits> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int maxn=300000+10; const int maxn1=100000+5; typedef long long ll; int n,k; struct node { int v,next,w; }tb[maxn*2]; int len,h[maxn]; ll f[maxn][5],g[maxn][5],qq[5],q[5]; ll ans,sum,sz[maxn],s,l,r; bool flag[maxn]; void add1(int i,int j,int w) { len++; tb[len]=(node){j,h[i],w}; h[i]=len; } void Max(ll &val,ll &num,ll newval,ll newnum) { if(val<newval || (val==newval && num>newnum)){val=newval,num=newnum;} } void dfs(int x,int fa) { f[x][0]=0; f[x][1]=-s; f[x][2]=-s; g[x][0]=0; g[x][1]=1; g[x][2]=1; for(int i=h[x]; i ;i=tb[i].next) { int v=tb[i].v; if(v==fa) continue; dfs(v,x); for(int j=0; j<=2; j++) { qq[j]=f[x][j]; q[j]=g[x][j]; } ll max1=f[v][0],maxnum=g[v][0]; Max(max1,maxnum,f[v][1],g[v][1]); Max(max1,maxnum,f[v][2],g[v][2]); Max(f[x][0],g[x][0],qq[0]+max1,maxnum+q[0]); Max(f[x][1],g[x][1],qq[1]+max1,maxnum+q[1]); Max(f[x][1],g[x][1],qq[0]+f[v][1]+tb[i].w,q[0]+g[v][1]); Max(f[x][2],g[x][2],qq[2]+max1,maxnum+q[2]); Max(f[x][2],g[x][2],qq[1]+f[v][1]+tb[i].w+s,q[1]+g[v][1]-1); } } int main() { int size = 256 << 20; //250M char*p=(char*)malloc(size) + size; __asm__("movl %0, %%esp\n" :: "r"(p) ); freopen("test.in","r",stdin); freopen("test.out","w",stdout); scanf("%d %d",&n,&k); for(int i=1; i<n; i++) { int x,y,w; scanf("%d %d %d",&x,&y,&w); add1(x,y,w); add1(y,x,w); if(w>0) r+=w; l=min(l,1LL*(-w)); } k++; while(l<r) { s=(l+r)>>1; dfs(1,0); ll max1=f[1][0],maxnum=g[1][0]; Max(max1,maxnum,f[1][1],g[1][1]); Max(max1,maxnum,f[1][2],g[1][2]); if(maxnum>k) l=s+1; else r=s; } s=l; dfs(1,0); ll max1=f[1][0],maxnum=g[1][0]; Max(max1,maxnum,f[1][1],g[1][1]); Max(max1,maxnum,f[1][2],g[1][2]); cout<<max1+k*s<<endl; return 0; }

相關推薦

[2018]

題目真滴皮 Orz rqy 思路 10分的暴力都沒拿到 10分直接求直徑 60分 容易?想到題目等價於求k+1條不相交的鏈 設狀態f[i][j][0/1/2]f[i][j][0/1/2] 表示以第i個節點為根的子樹用了j條鏈並且根和兒子連有

bzoj5252 [2018隊聯測]

相交 close play define nbsp namespace OS display code 斜率優化樹形dp?? 我們先將問題轉化成在樹上選K+1條互不相交路徑,使其權值和最大。 然後我們考慮60分的dp,直接維護每個點子樹內選了幾條路徑,然後該點和0/1/

LuoguP4383 [2018]lct

tmp problem name ace typename 路徑 選擇 出現 由於 LuoguP4383 [八省聯考2018]林克卡特樹lct https://www.luogu.org/problemnew/show/P4383 分析: 題意等價於選擇\(K\)條點不相

dp凸優化/wps二分學習筆記(洛谷4383 [2018]lct)

qwq 安利一個凸優化講的比較好的部落格 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有點問題 qwq 我還是詳細的講一下這個題+這個知識點吧。 還是先從題目入手。 首先我們分析題目。 因為題目要刪除

[2018]

style 獲取 getchar col include 狀態 現在 tdi 挑戰 題目描述 小L 最近沈迷於塞爾達傳說:荒野之息(The Legend of Zelda: Breath of The Wild)無法自拔,他尤其喜歡遊戲中的迷你挑戰。 遊戲中有一個叫做“LC

[LOJ#2478][九2018](樹形DP+帶權二分)

Address 洛谷P4383 BZOJ5252 LOJ#2478 Solution 簡版題意:在一棵 n n

2018

Link Difficulty 演算法難度7,思維難度7,程式碼難度5 Description 給定一棵nnn個點的樹,邊帶權值,要求你選出k+1k+1k+1條鏈,使得權值和最大。 1≤k&lt;n≤3×105,∣v∣≤1061\le k&lt;

[九2018]-Day2-劈配--制胡竄

說在前面 模擬考,只考了125,這題難的可以= = 被T2折磨致死 T3感覺複雜…懶得寫 題目 T1 連題目名字都提示了!!這就是一個最優匹配問題 像這樣的肯定和網路流(或者匈牙利)有關係,稍微思考一下就能出來,二分答案+網路流就好

#2478. 「九 2018

這題挺考思路的…我這種渣渣就是做不來. 大佬blog 想了半天,然後看題解了半天…思路還是看大佬的吧. c++程式碼如下: #include<bits/stdc++.h> #define rep(i,x,y) for(register i

LibreOJ #2478.「九 2018 樹形dp+帶權二分

題意 給出一棵n個節點的樹和k,邊有邊權,要求先從樹中選k條邊,然後把這k條邊刪掉,再加入k條邊權為0的邊,滿足操作完後的圖仍然是一棵樹。問新樹的帶權直徑最大是多少。 n,k≤3∗105n,k≤3∗105 分析 不難發現我們要求的就是在樹中選出k+1

[loj 2478][luogu P4843]「九 2018

遊戲 for legend tps reat 簡單 block math pap 傳送門 Description 小L 最近沈迷於塞爾達傳說:荒野之息(The Legend of Zelda: Breath of The Wild)無法自拔,他尤其喜歡遊戲中的迷你

【HEOI 2018

for 瓶頸 二分 close LG cli 就會 -c -i 先說60分的.思路題解上很清晰: 問題似乎等價於選K+1條點不相交的鏈哎!F(x,k,0/1/2)表示考慮以x為根的子樹,選了k條鏈,點x的度數為0/1/2的最優解. 我說一下比較坑的地方吧:1.初

[JZOJ5641] 【樹形DP】【凸優化】

Description 給定一棵n個節點的樹,邊有邊權(可能為負)。 你需要刪掉恰好K條邊,再連上恰好K條邊權為0的邊,並保證連完邊後這還是一棵樹,求這棵樹的最大的最長路長度。 K

[2018] 劈配

b+ con 誌願 break div -c 們的 其他 turn 題目背景 一年一度的綜藝節目《中國新代碼》又開始了。Zayid 從小就夢想成為一名程序員,他覺得這是一個展示自己的舞臺,於是他毫不猶豫地報名了。 題目描述 輕車熟路的Zayid 順利地通過了海選,接下來的環

解題:2018 劈配

人的 優先級 log 動態 結果 二分 tro problem 題解 題面 看起來就很像匹配問題嘛,連題目名都在提示你=。= 這題真是把匹配問題的細節發揮到了極致,不過還好送70,考場上應該不至於掛得太慘 那不如先說說70分的暴力怎麽寫 對於測試點2,3,n,m很小

[BZOJ5248] 2018 D1T1 一雙木棋 | 博弈論 狀壓DP

while 奇數 getchar OS cst blog || ios char 題面 菲菲和牛牛在一塊\(n\)行\(m\)列的棋盤上下棋,菲菲執黑棋先手,牛牛執白棋後手。 棋局開始時,棋盤上沒有任何棋子,兩人輪流在格子上落子,直到填滿棋盤時結束。 落子的規則是:一個格子

bzoj5248(洛谷4363)(2018)一雙木棋

In int CA 超時 tdi .org %d col DG 題目:https://www.luogu.org/problemnew/show/P4363 一種考慮狀態數的方法:有幾個用了k個格子的列,就在第k個0的左邊插入幾個1;   這也是求不降序列的個數的方法。本題

解題:2018 一雙木棋

turn 討論 names ret tps 高端 scanf 分享圖片 std 題面 我的常數可能是沒救了,明明寫的差不多,別人的都跑的飛快,就我的T到爆炸,卡常也卡不過去QAQ 我當初這個題手動討論拿了25pts,然後胡亂貪心搞了5pts 2333 還以為min-max對

2018 遊記

優先 兩個 發現 吃飯 排序 風格 多少 沒有 nor 前言: 作為一個SD的蒟蒻,我非常確信我就是來劃水的2333,希望我能進二輪吧hhhh DAY0: 玩了一上午2k之後,又去打了一下午球,,,晚上和幾個很好的朋友聊了聊天,收到了滿滿的鼓勵qwq。

【BZOJ5248】【九2018】一雙木棋(搜索,哈希)

count const 一個 body 如果 直接 一個人 沒有 span 【BZOJ5248】【九省聯考2018】一雙木棋(搜索,哈希) 題面 BZOJ Description 菲菲和牛牛在一塊n行m列的棋盤上下棋,菲菲執黑棋先手,牛牛執白棋後手。棋局開始時,棋盤上沒有任