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...