並查集入門

【簡介】 並查集(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; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章