P2387 NOI2014 魔法森林(LCT)

2022-04-30 09:09:07 字數 1224 閱讀 3755

p2387 [noi2014]魔法森林

lct邊權維護經典題

咋維護呢?邊化為點,邊權變點權。

本題中我們把邊對關鍵字a進行排序,動態維護關鍵字b的最小生成樹

加邊後出現環咋辦?

splay維護最大邊的編號,找到最大邊刪除再加新邊就ok辣

#include#include

using

namespace

std;

inline

void swap(int &a,int &b)

inline

int min(int a,int b)

void read(int &x)

#define n 200005

struct edgea[n];

int n,m,ans=2e9,ch[n][2

],fa[n],val[n],s[n],rev[n],dad[n];

#define lc ch[x][0]

#define rc ch[x][1]inline

bool cmp(edge p,edge q)

int find(int x)

inline

bool nrt(int x)

void up(int

x)void rev(int x)

void down(int x)

void pre(int x)

void turn(int

x)void splay(intx)}

void access(int x)

void makert(int

x)int findrt(int

x)void link(int x,int y)

void cut(int x,int

y)void split(int x,int

y)int

main()

else dad[r1]=r2;

link(a[i].f,i+n); link(i+n,a[i].t);

if(find(1)==find(n)) split(n,1),ans=min(ans,a[i].a+val[s[1

]]);

}if(ans>=2e9) puts("-1"

);

else printf("%d"

,ans);

return0;

}

P2387 NOI2014 魔法森林

p2387 noi2014 魔法森林 這題目花了點時間題解沒圖,其中一些操作不夠簡潔,常數比較大,都說 lct 常數小 時限 3000ms 最大點 500ms 反正過了 首先考慮做法 排序 a 順序加邊,然後動態維護最大 b 使生成樹最小,其中貢獻為最大的 b 這題是動態的,所以考慮 lct 但不同...

P2387 NOI2014 魔法森林(LCT)

將所有邊按a從小到大排序,加入一條新邊 u,v 時,檢查原先u和v是否連通,若連通則斷開舊路徑,新路徑上最大的b和新加入的邊的a相加,看能否更新答案。既然是動態加邊和刪邊,便考慮用lct。要查詢兩點間路徑上的最大值,所以點和邊都要建節點,並且維護最大的b和其對應的邊的標號。當加入新邊檢查是否兩點已聯...

luogu P2387 NOI2014 魔法森林

傳送門 這題似乎不好直接做,可以考慮按照 a i 公升序排序,然後依次加邊更新答案 具體實現方法是用lct維護當前的樹,這裡需要維護鏈上最大的 b i 每次加一條邊,如果加完以後沒有環直接加,否則找出鏈上最大的 b i 如果這個 b i 比當前的 b i 小,加了肯定不優,否則就把那條邊斷掉,加上這...