[洛谷]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;
}

 

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