最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++數(shù)據(jù)結(jié)構(gòu)之并查集詳解

 更新時(shí)間:2023年08月29日 09:59:56   作者:CodeRanger  
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之并查集詳解,并查集是一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合的合并及查詢問(wèn)題,并查集的思想是用一個(gè)數(shù)組表示了整片森林,需要的朋友可以參考下

一、概念:

并查集是一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合的合并及查詢問(wèn)題。

并查集的思想是用一個(gè)數(shù)組表示了整片森林(parent),樹(shù)的根節(jié)點(diǎn)唯一標(biāo)識(shí)了一個(gè)集合

我們只要找到了某個(gè)元素的的樹(shù)根,就能確定它在哪個(gè)集合里。

二、用法:

并查集用在一些有 N 個(gè)元素的集合應(yīng)用問(wèn)題中,我們通常是在開(kāi)始時(shí)讓每個(gè)元素構(gòu)成一個(gè)單元素的集合,然后按一定順序?qū)儆谕唤M的元素所在的集合合并,其間要反復(fù)查找一個(gè)元素在哪個(gè)集合中。

這個(gè)過(guò)程看似并不復(fù)雜,但數(shù)據(jù)量極大,若用其他的數(shù)據(jù)結(jié)構(gòu)來(lái)描述的話,往往在空間上過(guò)大,計(jì)算機(jī)無(wú)法承受,也無(wú)法在短時(shí)間內(nèi)計(jì)算出結(jié)果,所以只能用并查集來(lái)處理。

簡(jiǎn)述一下:

1,將兩個(gè)集合合并。

2,詢問(wèn)兩個(gè)集合是否在同一集合中。

三、基本原理:

每個(gè)集合用一顆樹(shù)來(lái)儲(chǔ)存。樹(shù)的根節(jié)點(diǎn)編號(hào)是每個(gè)集合的編號(hào)。

每個(gè)節(jié)點(diǎn)存儲(chǔ)它的父節(jié)點(diǎn),p[x]表示x的父節(jié)點(diǎn)。

四、常見(jiàn)問(wèn)題/要處理的問(wèn)題:

1,如何判斷樹(shù)根:if(p[x]==x)

2,如何求x的集合編號(hào): while(p[x]!=x) x=p[x] (對(duì)照用法二)

3,如何合并兩個(gè)集合:px是x的集合邊界,py是y的編號(hào)集合。p[x]=y

實(shí)踐題目:

一共有 n 個(gè)數(shù),編號(hào)是 1∼n,最開(kāi)始每個(gè)數(shù)各自在一個(gè)集合中。

現(xiàn)在要進(jìn)行 mm 個(gè)操作,操作共有兩種:

  • M a b ,將編號(hào)為 a 和 b 的兩個(gè)數(shù)所在的集合合并,如果兩個(gè)數(shù)已經(jīng)在同一個(gè)集合中,則忽略這個(gè)操作;
  • Q a b ,詢問(wèn)編號(hào)為 a 和 b 的兩個(gè)數(shù)是否在同一個(gè)集合中;

輸入格式

第一行輸入整數(shù) n 和 m。

接下來(lái) m 行,每行包含一個(gè)操作指令,指令為  M a b  或  Q a b  中的一種。

輸出格式

對(duì)于每個(gè)詢問(wèn)指令  Q a b ,都要輸出一個(gè)結(jié)果,如果 a 和 b 在同一集合內(nèi),則輸出  Yes ,否則輸出  No 。

每個(gè)結(jié)果占一行。

數(shù)據(jù)范圍

1≤n,m≤10^5   

1≤n,m≤10^5

輸入樣例:

4 5
M 1 2
M 3 4
Q 1 2
Q 1 3
Q 3 4

輸出樣例:

Yes
No
Yes

先上代碼:

#include<iostream>
using namespace std;
const int N = 100010;
int p[N];
int find(int x){
	if(p[x]!=x){
		p[x]=find(p[x]);
	}
	return p[x];
}
int main(){
	char op[2];
	int n,i,j,k,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		p[i]=i;
	}
	while(m--){
		int a,b;
		cin>>op>>a>>b;
		if(op[0]=='M'){
			p[find(a)]=find(b);
		}
		else{
			if(find(a)==find(b)){
				cout<<"Yes"<<endl;
			}
			else{
				cout<<"No"<<endl;
			}
		}
	}
	return 0;	
}

解讀思路:

初始化:由于一開(kāi)始我們得到的是幾個(gè)散亂的集合,即每個(gè)數(shù)都是一個(gè)集合,所以我們初始化為 p[x]=x ,這就表示他自己就是一個(gè)集合,也可以說(shuō)成他就是自己的父節(jié)點(diǎn)/祖宗節(jié)點(diǎn)。

集合合并與查找:假如我們有{1},{2}這兩個(gè)單獨(dú)集合,我們要把它合成一個(gè)集合,就需要把他們的祖宗節(jié)點(diǎn)變成一個(gè),就是上面說(shuō)到的 p[x]=p[y]=x

注:這里以誰(shuí)為父節(jié)點(diǎn)是按你輸入的順序定的馬,可以理解為隨機(jī)的,例如你第一個(gè)數(shù)是1,那么之后的想要把其他數(shù)都合并在1這個(gè)數(shù)的集合里,那么他們的父節(jié)點(diǎn)為 p[1]=p[2]=p[3]=....p[n]=1 )之后集合就成了{(lán)1 , 2}。

那么我們的查找操作也相應(yīng)完成了,既然都在一個(gè)集合里,都有一個(gè)父節(jié)點(diǎn),判斷兩個(gè)數(shù)是否在一個(gè)集合里直接比較父節(jié)點(diǎn)即可,高效準(zhǔn)確。

find()函數(shù):這里建議自己模擬一遍。如果此時(shí)我們已經(jīng)將1,2合并到一個(gè)集合中去,此時(shí)把1再執(zhí)行一邊f(xié)ind函數(shù),根據(jù)代碼:p[1]=2 -> !=1 -> p[1]=find(2) -> p[2]=2 -> return 2  結(jié)束函數(shù)。

好,我們加一問(wèn),詢問(wèn)某個(gè)數(shù)所在集合中的元素?cái)?shù)量。

代碼:

#include<iostream>
using namespace std;
const int N = 100010;
int p[N];
int siz[N];
int find(int x){
	if(p[x]!=x){
		p[x]=find(p[x]);
	}
	return p[x];
}
int main(){
	char op[2];
	int n,i,j,k,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		p[i]=i;
		size[i]=1;
	}
	while(m--){
		int a,b;
		cin>>op;
		if(op[1]=='1'){
			cin>>a>>b;
			if(find(a)==find(b)){
				cout<<"Yes"<<endl;
			}
			else{
				cout<<"No"<<endl;
			}
		}
		else if(op[0]=='C'){
			cin>>a>>b;
			if(find(a)==find(b)){
				continue;//注意特判,否則重復(fù)相加個(gè)數(shù)
			}
			siz[find(b)]+=siz[find(a)];
			p[find(a)]=find(b);
		}
		else{
			cin>>a;
			cout<<siz[find(a)]<<endl;
		}
	}
	return 0;	
}

思路大致相同,要找某個(gè)數(shù)所在集合中元素的個(gè)數(shù),我們也只需找到他的父節(jié)點(diǎn)的標(biāo)號(hào)下的元素個(gè)數(shù)即可。

我們需要開(kāi)一個(gè)size[]數(shù)組存放元素個(gè)數(shù),例如還是舉上面的例子:1,2,3在同一個(gè)集合里,他們的父節(jié)點(diǎn)是p[2]=2,那么他們的size的值也都變成size[2]=size[3]=size[1]=3,另外這個(gè)數(shù)組也是需要維護(hù)更新的

我們看具體操作:先初始化,size[i]=1,之后相加即可。

為什么siz[]里面的參數(shù)是find(x)呢,原因還是要找到相同的父節(jié)點(diǎn)。

到此這篇關(guān)于C++數(shù)據(jù)結(jié)構(gòu)之并查集詳解的文章就介紹到這了,更多相關(guān)C++并查集內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 華為云CodeArts?IDE?Online快速入門和使用

    華為云CodeArts?IDE?Online快速入門和使用

    華為云CodeArts?IDE?Online服務(wù),提供了可隨時(shí)隨地編碼的云上開(kāi)發(fā)環(huán)境,同時(shí)具備開(kāi)放的生態(tài)和獨(dú)立插件市場(chǎng),本文主要介紹了華為云CodeArts?IDE?Online快速入門和使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易連連看游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易連連看游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易連連看游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 深入C++實(shí)現(xiàn)函數(shù)itoa()的分析

    深入C++實(shí)現(xiàn)函數(shù)itoa()的分析

    本篇文章是對(duì)C++實(shí)現(xiàn)函數(shù)itoa()進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • VS2022 CUDA環(huán)境配置的實(shí)現(xiàn)步驟

    VS2022 CUDA環(huán)境配置的實(shí)現(xiàn)步驟

    本文主要介紹了VS2022 CUDA環(huán)境配置的實(shí)現(xiàn)步驟,文中通過(guò)圖文示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Qt利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的示例代碼

    Qt利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Qt如何利用QNetwork實(shí)現(xiàn)上傳數(shù)據(jù)的 功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-02-02
  • C++簡(jiǎn)易版Tensor實(shí)現(xiàn)方法詳解

    C++簡(jiǎn)易版Tensor實(shí)現(xiàn)方法詳解

    這篇文章主要介紹了C++簡(jiǎn)易版Tensor的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值
    2022-08-08
  • 如何利用C語(yǔ)言實(shí)現(xiàn)最簡(jiǎn)單的HTTP服務(wù)器詳解

    如何利用C語(yǔ)言實(shí)現(xiàn)最簡(jiǎn)單的HTTP服務(wù)器詳解

    這篇文章主要給大家介紹了關(guān)于如何利用C語(yǔ)言實(shí)現(xiàn)最簡(jiǎn)單的HTTP服務(wù)器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C語(yǔ)言具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • C++中vector<vector<int>?>的基本使用方法

    C++中vector<vector<int>?>的基本使用方法

    vector<vector<int>?>其實(shí)就是容器嵌套容器,外層容器的元素類型是vector<int>,下面這篇文章主要給大家介紹了關(guān)于C++中vector<vector<int>?>的基本使用方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • C語(yǔ)言編程計(jì)算信噪比SNR理解學(xué)習(xí)

    C語(yǔ)言編程計(jì)算信噪比SNR理解學(xué)習(xí)

    這篇文章主要介紹了C語(yǔ)言編程信噪比SNR計(jì)算的理解學(xué)習(xí),信噪比,英文名稱叫做SNR或S/N(SIGNAL-NOISE RATIO)。是指一個(gè)電子設(shè)備或者電子系統(tǒng)中信號(hào)與噪聲的比例
    2021-10-10
  • C++繼承和多態(tài)的用法解讀

    C++繼承和多態(tài)的用法解讀

    這篇文章主要介紹了C++繼承和多態(tài)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06

最新評(píng)論

龙口市| 南昌市| 林周县| 容城县| 平湖市| 临洮县| 岳西县| 保定市| 新巴尔虎右旗| 武邑县| 泽库县| 比如县| 南安市| 威信县| 河间市| 如东县| 望城县| 临沂市| 玉屏| 汉川市| 仪陇县| 溧水县| 香河县| 左云县| 昌黎县| 商洛市| 那坡县| 垫江县| 田阳县| 沭阳县| 阿瓦提县| 治多县| 金山区| 雷山县| 喀喇沁旗| 枣阳市| 苗栗市| 宝丰县| 江川县| 桐城市| 高州市|