lct動態維護最小生成樹的典例
這個都是套路,倒序處理,將刪邊變成加邊
再將邊換成點,然後就可以做到點權維護邊權資訊
說一下加邊的過程大概是
一、首先最小生成樹,保證初始最優
二、對於新加入的一條邊,找出原x->y鏈上的最大邊,替換
第二點的實現比較有意思
因為是在樹上加邊,所以一定會形成乙個環,那麼我們要使邊權和最小,就要刪邊
分為兩種情況,一種是新加入的邊比換上的最大邊還要大,就不用管
但是如果比最大邊小,就cut掉最大邊,link新邊即可
如何維護最大邊權呢
上面說了,將邊換成點,然後就愉快的變成了統計路徑上點的最大值
說起來很簡單,然後邊換點的操作實在是有點喪心病狂
讓我改了n久…
大部分都是板子,主要講講主程式的預處理和新的pushup
**
#include
#include
#include
#include
#include
using
namespace std;
const
int maxn =
200007
;struct edge
e[maxn]
;struct node
task[maxn]
;int n,m,q,lazy[maxn]
,c[maxn][2
],roundmax[maxn]
,val[maxn]
,fa[maxn]
,st[maxn]
,top;
bool
isroot
(int k)
void
pushdown
(int k)
}void
pushup
(int k)
void
rotate
(int k)
void
splay
(int k)
}void
access
(int k)
}void
makeroot
(int x)
void
link
(int x,
int y)
void
cut(
int x,
int y)
intquery
(int x,
int y)
bool
cmp1
(edge a,edge b)
bool
cmp2
(edge a,edge b)
bool
c***
(edge a,edge b)
intfindedge
(int u,
int v)
// 這裡很蠢的寫了乙個手動二分,為了找到刪除的邊
}int f[maxn]
;int
find
(int x)
// kruskal
void
kru()}
intmain()
sort
(e+1
,e+m+
1,cmp2)
;// 排序,然後對邊編號
for(
int i=
1;i<=m;i++
)sort
(e+1
,e+m+
1,cmp1)
;for
(int i=
1;i<=q;i++)}
kru();
// 生成樹
for(
int i=q;i>=
1;i--)}
}for
(int i=
1;i<=q;i++
)// 輸出,撒花
if(task[i]
.opt==1)
printf
("%d\n"
,task[i]
.ans)
;return0;
// ^_^結束
}
洛谷P4172 WC2006 水管局長
sc省my市有著龐大的地下水管網路,嘟嘟是my市的水管局長 就是管水管的啦 嘟嘟作為水管局長的工作就是 每天供水公司可能要將一定量的水從x處送往y處,嘟嘟需要為供水公司找到一條從a至b的水管的路徑,接著通過資訊化的控制中心通知路徑上的水管進入準備送水狀態,等到路徑上每一條水管都準備好了,供水公司就可...
P4172 WC2006 水管局長
題目鏈結 題目背景 sc 省 my 市有著龐大的地下水管網路,嘟嘟是 my 市的水管局長 就是管水管的啦 題目描述 每天供水公司可能要將一定量的水從 u uu 處送往 v vv 處,嘟嘟需要為供水公司找到一條從 u uu 至 v vv 的水管的路徑,接著通過資訊化的控制中心通知路徑上的水管進入準備送...
P4172 WC2006 水管局長
bzoj 那個是加強版 lct 維護動態最小瓶頸樹 題意 給乙個圖,每次詢問兩個點之間路徑的最大值的最小值,或斷開乙個邊,始終保證圖連通 用 lct 維護,發現斷邊不怎麼好做,所以離線下來倒序處理,常規套路 就是先跑乙個最小瓶頸生成樹,然後每次加邊,如果加的這個邊的邊權大於它兩個端點間原來路徑的最大...