p2387 [noi2014]魔法森林
lct邊權維護經典題
咋維護呢?邊化為點,邊權變點權。
本題中我們把邊對關鍵字a進行排序,動態維護關鍵字b的最小生成樹
加邊後出現環咋辦?
splay維護最大邊的編號,找到最大邊刪除再加新邊就ok辣
#include#includeusing
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 小,加了肯定不優,否則就把那條邊斷掉,加上這...