NOI模擬 Vain (並查集維護割點)

2021-08-17 16:50:10 字數 2131 閱讀 8342

題意:

對於 1 ≤ i ≤ n, 求出點 i 度數強制為 1 的情況下最小生成樹的最大邊的權值。

題解:

相當於求出刪掉每個點之後的ms

t mst

的最大值。

我們按邊的權值從小到大加入新圖, 很顯然當乙個點不是割點的時候這條邊就是它對應的答案。

先建出mst,然後動態加邊。

我們要維護每個點

i i

的每個子樹

j' role="presentation">jj連到

fai fai

的最早的時間hj

h

j,同時要維護子樹之間最早的相連邊。

第二個直接在lc

a(x,

y)l ca

(x,y

)處並查集維護,對於第乙個,一條邊(x

,y) (x,

y)

的能更新的

h h

的區間是x→

lca(

x,y)

' role="presentation">x→l

ca(x

,y)x

→lca

(x,y

), y→

lca(

x,y)

y →l

ca(x

,y

)。同樣並查集維護還沒有被更新的點即可。

#include 

using

namespace

std;

typedef

vector

::iterator it_v;

const

int rlen=1

<<18|1;

inline

char nc()

inline

int rd()

while(isdigit(ch))

return i*f;

}inline

void w(int x)

if(x<0)

while(x)

while(buf[0])

}const

int n=1e6+50,lim=20,inf=0x3f3f3f3f;

int n,m,anc[n],up[n],fa[n][lim],dep[n],mn[n],mnv;

int h[n];

struct e e[n];

vector

edge[n];

vector

link_son[n];

inline

int ga(int x)

inline

int gu(int x)

inline

int jump(int x,int d)

inline

int get_lca(int x,int y)

inline

int dfs(int x,int f)

inline

int group(int x,int f,int v)

}inline

void link(int x,int y,int t) );

}}int main()

sort(e+1, e+m+1, [&](const e &a,const e &b)

}for(int i=1;i<=n;i++)

if(ga(i)!=ga(1))

for(int i=1;i<=n;i++) sort(edge[i].begin(), edge[i].end());

dfs(1,0);

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

long

long sum=0;

for(int i=1;i<=n;i++) , anc[v]=v;

for(auto v:link_son[i])

stk[++tl]=v;

sort(stk+1,stk+tl+1,[&](const e &a,const e &b)

if(ans==inf) break;

} sum+= (ans1);

}cout

<}

NOI 食物鏈 並查集補集

題目描述 動物王國中有三類動物 a,b,c,這三類動物的食物鏈構成了有趣的環形。a 吃 b,b 吃 c,c 吃 a。現有 n 個動物,以 1 n 編號。每個動物都是 a,b,c 中的一種,但是我們並不知道 它到底是哪一種。有人用兩種說法對這 n 個動物所構成的食物鏈關係進行描述 第一種說法是 1 x...

noip模擬 心《並查集》

背景描述 不是一切深淵都是滅亡 不是一切滅亡都覆蓋在弱者的頭上 這也是一切 舒婷 有n個透明的盒子,每個盒子裡面有兩個不同顏色的球,總共有m種顏色。alice和bob又在玩遊戲,具體的,alice會從n個盒子裡面選出若干個,bob再從alice選出的盒子裡面選出一些 不能不選 如果在bob選出的盒子...

NOI2002 帶權並查集

題意 共有30000個人,編號為1 30000,開始時每個人一列。然後進行兩種操作 m i j表示把第i個人所在的列的隊首加到第j個人所在的列的隊尾。c i j查詢第i個人和第j個人是否在一列,假如在一列詢問i和j間隔著幾個人。題解 1.不同於以前的帶權並查集,這個除了fa陣列和d陣列外,加了乙個n...