並查集是經典的圖論演算法,用來維護點與集合的關係,**也簡潔明瞭。
給定 n
nn 個點,有 m
mm 次操作,每次操作輸入 pppa
aab
bb 。
若 p =1
p = 1
p=1 ,則 合併 aaab
bb;
若 p =2
p = 2
p=2 ,則 查詢 aaab
bb 是否同屬乙個集合;
並查集初始化:每個父親點 都 儲存 兒子的資訊:
for
(int i =
1; i <= n; i++
) fa[i]
= i;
並查集的查詢(路徑壓縮版):
int
find
(int x)
並查集的合併:
int x =
find
(a), y =
find
(b);
if(x != y) fa[x]
= y;
並查集模版完整**:
#include
#include
using
namespace std;
int n,m;
int fa[
1001000];
intfind
(int x)
intmain()
}return0;
}
訓練題目:
[模版]並查集
[模版]最小生成樹
有些特殊的題目需要對並查集進行變形,比如合併的時候統計當前連通塊的大小,這時候需要對 查詢或者合併操作進行對應修改。
銀河英雄傳說
[usaco04open]cube stacking
例二**:
#include
#include
using
namespace std;
int p,a,b;
int fa[
33000
],sum[
33000
],dist[
33000];
char ch;
intfind
(int x)
void
unite
(int x,
int y)
intmain()
if(ch ==
'c')
}return0;
}
還有一些開多倍並查集的題目,來表示朋友或敵人的關係。如果題目要求給定資料是不在同乙個集合,則可以令 u
uu 和 v+n
v+nv+
n 聯合在一起。
boi團夥
noi食物鏈
noip關押罪犯
例二**:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
const
int maxn =
50000+50
;int fa[maxn <<2]
;int
read()
while
(ch >=
'0'&& ch <=
'9')
return rt * in;
}int
find
(int x)
void
unite
(int x,
int y)
intmain()
if(ins ==1)
if(find
(x+n)
==find
(y)||
find
(x+2
*n)==
find
(y)||
find
(x)==
find
(y+n)
||find
(x)==
find
(y+2
*n))
else
unite
(x, y)
,unite
(x+n, y+n)
,unite
(x+2
*n, y+
2*n)
;elseif(
find
(x)==
find
(y)||
find
(y)==
find
(x+n)
)else
unite
(x, y+n)
,unite
(x+n, y+
2*n)
,unite
(x+2
*n, y);}
printf
("%d\n"
,ans)
;system
("pause");
return0;
}
模版 並查集
什麼是並查集 並查集是一種樹型的資料結構,用於處理一些不相交集合 disjoint sets 的合併及查詢問題。為何使用inline inline是c 關鍵字,在函式宣告或定義中,函式返回型別前加上關鍵字inline,即可以把函式指定為內聯函式。這樣可以解決一些頻繁呼叫的函式大量消耗棧空間 棧記憶體...
並查集 模版
並查集 並查集,在一些有n個元素的集合應用問題中,我們通常是在開始時讓每個元素構成乙個單元素的集合,然後按一定順序將屬於同一組的元素所在的集合合併,其間要反覆查詢乙個元素在哪個集合中。這一類問題近幾年來反覆出現在資訊學的國際國內賽題中,其特點是看似並不複雜,但資料量極大,若用正常的資料結構來描述的話...
疊積木(加權並查集)
題目描述 約翰和貝西在疊積木。共有30000塊積木,編號為1到30000。一開始,這些積木放在地上,自然地分成n堆。貝西接受約翰的指示,把一些積木疊在另一些積木的上面。一旦兩塊積木相疊,彼此就再也不會分開了,所以最後疊在一起的積木會越來越高。約翰讓貝西依次執行p條操作,操作分為兩種 第一種是移動操作...