並查集的操作有三步,初始化,查詢祖先與合併。
既然並查集是來查詢祖先的,那麼初始化就必然是讓每個點的祖先指向自己
for(int i=1;i<=n;++i) fa[i]=i;
查詢操作就是不斷地向上走,直到找到祖先為止
while(x!=fa[x]) x=fa[x];
合併操作就是把乙個節點的祖先變為另乙個節點的祖先。
fa[find(a)]=find(b);//其中find(x)為x的祖先
我們需對路徑進行壓縮。
即當我們經過找到祖先節點後,回溯的時候順便將它的子孫節點都直接指向祖先,使以後的查詢複雜度變回o(logn)甚至更低
while(x!=fa[x]) x=fa[x]=fa[fa[x]];
完整**:
#include#include#include
#include
#include
#include
#include
#include
#include
#include
using
namespace std;
typedef long
long
ll;typedef
long
double
ld;typedef pair
pr;const
double pi=acos(-1
);#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define rep(i,u) for(int i=head[u];i;i=next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define fi first
#define sc secondld eps=1e-9
;ll pp=1000000007
;ll mo(ll a,ll pp)
ll powmod(ll a,ll b,ll pp)
ll read()
//head
intn,m,p,x,y,z;
int fa[20005
];int find_die(int x)//
找爹函式
void uni(int r,int k)//
合併函式
inline
void print(int x,int y)//
輸出函式
intmain()
else
if(z==2
) print(x,y);
}return0;
}
並查集(模板題)
並查集是一種樹形的資料結構,用於處理一些不相交集合的合併及查詢問題。並查集通過乙個一維陣列來實現。1 查詢元素a和元素b是否屬於同一集合 2 合併元素a和元素b所在的集合 第一步 初始化 void init int n 第二步 查詢根節點 即找祖先 遞迴版本 int find f int x 不停找...
並查集模板題 P3367 模板 並查集
如題,現在有乙個並查集,你需要完成合併和查詢操作。第一行包含兩個整數n m,表示共有n個元素和m個操作。接下來m行,每行包含三個整數zi xi yi 當zi 1時,將xi與yi所在的集合合併 當zi 2時,輸出xi與yi是否在同一集合內,是的話輸出y 否則話輸出n 如上,對於每乙個zi 2的操作,都...
找朋友並查集裸題
找朋友 並查集用來合併兩個不相交的集合 主要找根,需要路徑優化 合併的時候按秩合併 ac include using namespace std const int maxn 5e4 int parent maxn rank1 maxn int m,n,p struct frda maxn b ma...