【簡介】 並查集(Union Find)是一種用於管理分組的數據結構。它具備兩個操作:(1)查詢元素a和元素b是否爲同一組 (2) 將元素a和b合併爲同一組。
核心代碼:
1.查詢代碼
int find(int k){//尋找根節點
if(node[k].father==k)
return k;
else{
node[k].father=find(node[k].father);//路徑壓縮,一路上每次函數返回時順便把其指向的父節點直接改爲根節點
////即直接把這個點掛到根節點上
return node[k].father;
}
}
2.合併代碼
void merge(int u,int v)//uX,v爲Y
{
u=find(u);v=find(v);//u,v爲根節點
if(node[u].rank>node[v].rank)//如果u的子節點深度大於v的話,u爲v的根節點
node[v].father=u;
else{
node[u].father=v;//同上
if(node[u].rank==node[v].rank)//如果深度相等
node[v].rank++;//v的深度+1;
}
}
模板題: P3367 【模板】並查集
代碼:
#include<cstdio>
#include<cstdlib>
using namespace std;
#define INF 10000+5
#define INF2 200000+5
int n,m;
struct Node{//寫大寫是爲了避免與之後的node重複
//int data;
int rank;//rank代表這一個節點和他的所有子節點的深度
int father;
}node[INF+1];
int get_bigfather(int k)//尋找根節點 ——一般是在這裏加上路徑壓縮的
{
if(node[k].father==k)
return k;
else
{
node[k].father=get_bigfather(node[k].father);//路徑壓縮——一路上每次函數返回時順便把其指向的父節點直接改爲根節點
//即直接把這個點掛到根節點上
return node[k].father;
}
}
void merge(int u,int v)
{
u=get_bigfather(u);
v=get_bigfather(v);
if(node[u].rank>node[v].rank)
node[v].father=u;
else
{
node[u].father=v;
if(node[u].rank==node[v].rank)
node[v].rank++;
}
}
int main()
{
scanf("%d%d",&n,&m);//n個元素,m個操作
for(int i=1;i<=n;i++)//初始化,自己的父親一開始是自己
node[i].father=i;
for(int i=1;i<=m;i++)
{
int temp,u,v;
scanf("%d%d%d",&temp,&u,&v);
if(temp==1)//合併
merge(u,v);
else
{
if(get_bigfather(u)==get_bigfather(v))
printf("Y\n");
else
printf("N\n");
}
}
return 0;
}