並查集的原理很簡單:在下標對應的陣列中寫入當前下標的父節點,說明當前節點和父節點有羈絆,無數個子節點連線著乙個父節點,如果要想判斷兩個節點之間是否有羈絆,只需對一對他們的父輩(根節點)就行了。並查集一般用於查詢圖中節點之間的關係。並查集演算法一般包括3大部分:
find()函式用來確定某節點x1的父親節點:
int
find
(int x)
//迴圈查詢x的根節點
int
find_dg
(int x)
//遞迴地查詢x的根節點
join()函式在兩個根節點之間建立羈絆:
void
join
(int x,
int y)
//鏈結兩個根節點
union()函式用來判斷兩個根節點誰做誰的父節點:
void
union
(int i,
int j)
題目描述
若某個家族人員過於龐大,要判斷兩個是否是親戚,確實還很不容易,現在給出某個親戚關係圖,求任意給出的兩個人是否具有親戚關係。
規定:x和y是親戚,y和z是親戚,那麼x和z也是親戚。如果x,y是親戚,那麼x的親戚都是y的親戚,y的親戚也都是x的親戚。
輸入格式
第一行:三個整數n,m,p,(n<=5000,m<=5000,p<=5000),分別表示有n個人,m個親戚關係,詢問p對親戚關係。
以下m行:每行兩個數mi,mj,1<=mi,mj<=n,表示ai和bi具有親戚關係。
接下來p行:每行兩個數pi,pj,詢問pi和pj是否具有親戚關係。
輸出格式
p行,每行乙個』yes』或』no』。表示第i個詢問的答案為「具有」或「不具有」親戚關係
輸入樣例
6 5 3
1 21 5
3 45 2
1 31 4
2 35 6
輸出樣例
yesyes
no首先,先將親戚之間的關係全都體現在pre中,用join()函式來判斷並記錄兩點關係。判斷某節點根節點用findx()函式。最後再查證m對節點是否有羈絆。
#include
#include
#include
#define maxn 5005
#define m 1e9+5
using
namespace std;
typedef
long
long ll;
using
namespace std;
int pre[maxn]
;int
findx
(int x)
void
join
(int x,
int y)
intmain()
for(
int i=
0;i)for
(int i=
0;i)else
}return0;
}
qbzt寒假 並查集
並查集 kruscal tarjan 求 lca 分類並查集 食物鏈,團夥 敵人的敵人是我的朋友 帶權並查集 sdoi2016 齒輪 可用 int father int x 建邊 任意相鄰兩格仔之間建邊,權值為海拔差 將邊排序,從小往大乙個乙個往裡加,當乙個並查集內部有起點,並且大小 點數 t,這裡...
寒假訓練報告1 26(並查集)
今天聽隊友講課講了並查集,好像比去年聽的時候更明白了一些。同時,知道了除了普通並查集,還有種類並查集和帶權並查集等。對於種類並查集的建模能力還有待提高,帶權並查集可能又得下乙個階段才能學習了。三個重要函式 void init int n int find int x void union int x...
並查集 並查集
本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...