3669 Noi2014 魔法森林 LCT

2021-07-09 09:03:14 字數 1347 閱讀 5329

這一定是我今天犯sb錯誤最多的一道題qaq

先說一下做法吧:

這個題有兩個限制條件,a[i]和b[i]。如果只有乙個的話,我們可以直接做mst或者二分答案。兩個該怎麼做呢?

依然這樣考慮,我們按照a[i]的權值來做mst,逐漸加邊的過程中,a是遞增的,所以我們要維護的是b的最大值。如果加入邊(u,v)時,u與v不相連(ufs維護),我們就連上這條邊,如果u與v相連,那麼加入這條邊必定會產生乙個環,我們要找的就是這個環上的最大邊(即加入前u->v路徑上的最大邊)刪去,保證依舊是一顆生成樹。動態維護mst就可以用lct來解決了。

維護邊的時候,直接維護不好維護,可以把邊轉化成點來維護。

注意:

access,cut等操作後不要忘記pushup!!!

#include

#define n 200005

#define inf 1000000007

using namespace std;

int n,m,ans,top;

intq[n],mx[n],val[n],f[n],fa[n],tree[n][2];

bool rev[n];

struct node e[n>>1];

inline int

read()

while (c>='0'&&c<='9')

return a*f;

}int find(int i)

inline bool cmp(node a,node b)

inline void pushup(int

x)inline void pushdown(intx)}

inline void rotate(int

x)inline void splay(int

x) rotate(x);

}}inline void access(int

x)inline void rever(int

x)inline void cut(int

x,int

y)inline void link(int

x,int

y)int query(int

x,int

y)int main()

}val[n+i]=e[i].b; mx[n+i]=n+i;

link(e[i].u,n+i); link(e[i].v,n+i);

if (find(1)==find(n)) ans=min(ans,e[i].a+val[query(1,n)]);

}ans==inf?puts("-1"):printf("%d",ans);

return

0;}

3669 Noi2014 魔法森林

為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為1.n,邊標號為1.m。初始時小e同學在號節點1,隱士則住在號節點n。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有人經過一條邊的時候,這條...

bzoj3669 NOI2014 魔法森林

給定n個點m條邊的無向圖,每條邊有兩個權值a與b。求一條1到n的路徑使得路徑經過邊的最大a與最大b的和最小。無法到達輸出 1。n 50000,m 100000。我們嘗試列舉路徑的最大a值,那麼我們只需按照a排序按順序插入,維護1到n的b最大值即可。用並查集維護連通性。當加入j到k這條邊時如果形成環,...

bzoj 3669 Noi2014 魔法森林

description 為了得到書法大家的真傳,小e同學下定決心去拜訪住在魔法森林中的隱士。魔法森林可以被看成乙個包含個n節點m條邊的無向圖,節點標號為1.n,邊標號為1.m。初始時小e同學在1號節點,隱士則住在號節點n。小e需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有...