[洛谷]P3367模板(並查集)

題意:

如題,現在有一個並查集,你需要完成合並和查詢操作。

分析:

開始學習並查集。並查集有兩種方式優化:按秩合併路徑壓縮按秩合併中的秩指的是樹的深度,即總是將更小的樹連接至更大的樹上。路徑壓縮是一種在執行“查找”時扁平化樹結構的方法。關鍵在於在路徑上的每個節點都可以直接連接到根上。

代碼(只按秩合併):

#include<bits/stdc++.h>
using namespace std; 
int father[10010],R[10010];
//建立一個新的集合,每一個子節點就是一個數,本身就是他的根節點
void Make_Set(int x){
    father[x] = x;          //根節點
    R[x] = 0;      //秩大小
}
 
//通過遞歸向上查找根節點,回溯時改變當前節點的父節點,直接指向根節點。
int Find_Set(int x){
    if(x != father[x])
        father[x] = Find_Set(father[x]);
    return father[x];
 
}
 
//兩個集合的合併算法
void Union(int x, int y){
    int GrandX = Find_Set(x);
    int GrandY = Find_Set(y);
 
    if(GrandX == GrandY)
        return;
    if(R[GrandX] < R[GrandY])
        father[GrandX] = GrandY;
    else{
        if(R[GrandX] == R[GrandY])
            R[GrandX]++;
        father[GrandY] = GrandX;    
    }
}

int main(){
	int n,m,z,x,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		Make_Set(i);
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&z,&x,&y);
		if(z==1){
			Union(x,y);
		}else{
			if(Find_Set(x)==Find_Set(y))
				printf("Y\n");
			else
				printf("N\n");
		}
	}
	return 0;
}

代碼(再經過路徑壓縮優化):

#include<bits/stdc++.h>
using namespace std; 
int father[10010],R[10010];
//建立一個新的集合,每一個子節點就是一個數,本身就是他的根節點
void Make_Set(int x){
    father[x] = x;          //根節點
    R[x] = 0;      //秩大小
}
 
//查找的同時進行路徑壓縮。
int Find_Set(int x){
    while(x != father[x]){
    	father[x]=father[father[x]];
    	x=father[x];
	}
    return x;
 
}
 
//兩個集合的合併算法
void Union(int x, int y){
    int GrandX = Find_Set(x);
    int GrandY = Find_Set(y);
 
    if(GrandX == GrandY)
        return;
    if(R[GrandX] < R[GrandY])
        father[GrandX] = GrandY;
    else{
        if(R[GrandX] == R[GrandY])
            R[GrandX]++;
        father[GrandY] = GrandX;    
    }
}

int main(){
	int n,m,z,x,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		Make_Set(i);
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&z,&x,&y);
		if(z==1){
			Union(x,y);
		}else{
			if(Find_Set(x)==Find_Set(y))
				printf("Y\n");
			else
				printf("N\n");
		}
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章