bzoj3669 Noi2014 魔法森林

2022-05-24 01:18:12 字數 1601 閱讀 8623

題目大意:有一張$n$個點,$m$條邊的無向圖,第$i$條邊有權值$a_i,b_i$,求一條$1$到$n$的路徑,使得這條路徑上$\max\+\max\$最小

題解:先想到二分,然而兩個權值,有沒有關鍵字先後順序的二分我並不會。。。

然後發現,可以先按$a_i$把每條邊排序,一條一條加入。若一條邊的端點原來就已經連線,就找到原來路徑上$\max\$,把這條邊刪去,再加上這條新的邊。如果這時$1->n$已經連通,就更新答案。$lct$

可以用$lct$來維護路徑最大值即可

卡點:$access$時斷重邊斷錯

c++ code:

#include #include #define maxn 50010

#define maxm 100010

#define n maxn + maxm

#define lc(x) son[x][0]

#define rc(x) son[x][1]

const int inf = 0x3f3f3f3f;

int n, m, ans = inf;

int fa[n], son[n][2], tg[n], mx[n];

int w[n];

inline int get(int rt)

inline bool isrt(int rt)

inline void swap(int &a, int &b)

inline void swap(int rt) ;

inline void pushdown(int rt)

inline int gmax(int a, int b)

inline void pushup(int rt)

inline void rotate(int x)

int s[n], top;

inline void splay(int x)

inline void access(int rt)

inline void mkrt(int rt)

inline void link(int x, int y)

inline void split(int x, int y)

inline void cut(int x, int y)

inline int getmax(int x, int y)

inline bool connect(int x, int y)

struct edge

} e[maxm];

inline int min(int a, int b)

int main()

std::sort(e, e + m);

for (int i = 0; i < m; i++)

} if (connect(1, n)) ans = min(ans, e[i].a + w[getmax(1, n)]);

} if (ans == inf) puts("-1");

else printf("%d\n", ans);

return 0;

}

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需要通過這一片魔法森林,才能夠拜訪到隱士。魔法森林中居住了一些妖怪。每當有...

bzoj 3669 NOI2014 魔法森林

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