*(貌似要省選了?似乎不關我這個蒟蒻的事,還是給oiers們加油吧!)
第一次學到了邊轉換為點的神奇操作。
luogu傳送門:
由於要找路徑上的最小的最長度(很繞自理解),還是很容易就想到最小生成樹的。再由於想到維護最小生成樹的時候刪邊還是很複雜的就想到這道題的刪邊離線倒著來做,將刪邊轉換成加邊來做就吼了。
但是權值全是在邊上的,怎麼來搞(只會點上的lct)。。於是翻了題解,發現了神奇的操作---》將邊轉換成點來操作,邊轉成的點權值便是邊權值,點編號為n+邊編號。因此這樣就搞定了儲存問題。
考慮維護最小生成樹,由於是倒著來考慮,因此在結尾是可以用kruskal或者prim來搞出一張最小生成樹的圖的,這裡就直接link一下起點與邊點然後link一下邊點和終點就可以了。詢問時也很簡單,setroot(x),access(y),splay(y),return dat[mx[y]]就找到了路徑上的最大路。
相對較複雜的是加邊操作。不過由於這是乙個最小生成樹,所以加邊(x,y)之後肯定會出現乙個環的。而我們先找到這條路徑(x,y)上的最大路,判斷加的邊權是否小於這個最大路,小於就先cut掉最大路,然後link(x,y)進去,否則就不管這個加邊,就這樣就始終用lct維護好了一棵最小生成樹。
#include#define zig(x) zigzag(x,1)#define zag(x) zigzag(x,2)
using namespace std;
int bingchafa[1005];
int gf(int x)
struct edge
bian[200005];
int n,m,q; int bianid[1005][1005],bianxx[200005],bianyy[200005];
int bbian[1005][1005];
struct cz
caozuo[200005];
bool operator<(const edge &aa,const edge &bb)
void zigzag(int x,int knd)
fa[x]=z; fa[y]=x;
if(knd==1)
else
putup(y); putup(x);
}void putdowmall(int x)
void splay(int x)
else
else
}else
else }}
}}void acc(int x)
}void setroot(int x)
void link(int x,int y)
void cut(int x,int y)
int main()
for(int i=1;i<=q;i++)
}sort(bian+1,bian+1+m);
int dian=n-1;
int x,y;
for(int i=1;i<=n;i++) bingchafa[i]=i;
for(int i=1;i<=m;i++)
for(int i=q;i>=1;i--)
else}}
for(int i=1;i<=q;i++)
}
WC2006 水管局長
傳送門 今天終於找到了一種比較方便好懂的用lct維護生成樹的辦法。以前用 mrclr 的方法 不是很理解,然後我寫在這道題的時候還錯了 首先先看一下這道題。這很明顯就是讓我們動態的維護乙個最小生成樹。不過因為刪邊的過程很難維護,所以我們改成先把邊存起來,之後倒序回加。一開始我們先用lct模擬krus...
題解 WC2006 水管局長
感覺這題好強啊 本來以為能過,結果毫無疑問的被ge了一頓 在這裡記錄一下做的過程,也免得以後又忘記啦。首先,我們應看出在這張圖上,要讓經過的水管最長的最短,就是要維護一棵動態的最小生成樹。只是刪除邊不是很好操作,所以我們將刪邊改為加邊,反向處理。如果發現新加的邊可以更新最小生成樹,我們就應該更新圖,...
WC2006 水管局長資料加強版
sc省my市有著龐大的地下水管網路,嘟嘟是my市的水管局長 就是管水管的啦 嘟嘟作為水管局長的工作就是 每天供水公司可能要將一定量的水從x處送往y處,嘟嘟需要為供水公司找到一條從a至b的水管的路徑,接著通過資訊化的控制中心通知路徑上的水管進入準備送水狀態,等到路徑上每一條水管都準備好了,供水公司就可...