P5631 最小mex生成樹 線段樹,並查集

2021-10-14 16:44:11 字數 1947 閱讀 2850

n

nn個點m

mm條邊的一張圖,求mex

mexme

x值最小的一棵生成樹。

考慮比較暴力的做法,列舉答案,然後判斷其他邊能否構成一棵生成樹。

發現一條邊會被重複加入多次,可以考慮不刪除其他不動的邊。

ww的邊,每次把w

ww丟到[1,

w−1]

∪[w+

1,∞]

[1,w-1]\cup[w+1,\infty]

[1,w−1

]∪[w

+1,∞

]這個區間。

時間複雜度o(n

log⁡

nlog⁡w

)o(n\log n\log w)

o(nlog

nlogw)

#include

#include

#include

#include

#include

using

namespace std;

const

int n=

1e6+

10,l=

1e5+2;

struct linecl[n]

;int n,m,cnt,fa[n]

,siz[n]

;vector v[n<<1]

;int

read()

while

(isdigit

(c))

return x*f;

}int

find

(int x)

void

unionm

(int x,

int y)

; siz[x]

+=siz[y]

;fa[y]

=x;return;}

void

clear_to

(int w)

return;}

void

change

(int x,

int l,

int r,

int l,

int r,line w)

int mid=

(l+r)

>>1;

if(r<=mid)

change

(x*2

,l,mid,l,r,w)

;else

if(l>mid)

change

(x*2+1

,mid+

1,r,l,r,w)

;else

change

(x*2

,l,mid,l,mid,w)

,change

(x*2+1

,mid+

1,r,mid+

1,r,w)

;return;}

intsolve

(int x,

int l,

int r)

int mid=

(l+r)

>>

1,k;

if(k=

solve

(x*2

,l,mid)

)return k;

if(k=

solve

(x*2+1

,mid+

1,r)

)return k;

clear_to

(top)

;return0;

}int

main()

);if(w!=l)

change(1

,1,l,w+

1,l,

(line));

}printf

("%d\n"

,solve(1

,1,l)-1)

;return0;

}

P5631 最小mex生成樹 線段樹,並查集

n 個點 m 條邊的一張圖,求 mex 值最小的一棵生成樹。考慮比較暴力的做法,列舉答案,然後判斷其他邊能否構成一棵生成樹。發現一條邊會被重複加入多次,可以考慮不刪除其他不動的邊。時間複雜度 o n log n log w include include include include includ...

洛谷P5631 最小mex生成樹

給定 n 個點 m 條邊的無向連通圖,邊有邊權。設乙個自然數集合 s 的 text 為 最小的 沒有出現在 s 中的自然數。現在你要求出乙個這個圖的生成樹,使得其邊權集合的 text 盡可能小。n leq 10 6,m leq 2 times 10 6,w i leq 10 5 很套路的線段樹分治。...

並查集 最小(最大)生成樹

首先給出並查集基本 int fa maxn rank maxn 基礎陣列,fa陣列儲存上乙個節點,rank表示節點級數 比較少用 初始化 void init int n 查詢 int find int x void combine int a,int b 判斷 bool issame int a,i...