并查集的相关知识详解 Come baby!!!
一:并查集的相關(guān)知識(shí)
這道題用到了并查集,所以我就學(xué)了一下并查集,所以把自己的見(jiàn)解也分享給大家(建議 先看視頻 再瀏覽 博客 再自己敲一遍 學(xué)習(xí)效率高而已,我總是亂著來(lái) 以為看幾篇博客就會(huì)了,其實(shí)最后還是老老實(shí)實(shí) 去B站看大佬講解視頻 才搞懂)
1:并查集
并查集是一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),
用于處理一些不相交集合(Disjoint Sets)的合并及查詢(xún)問(wèn)題
1:查詢(xún)?cè)豠和元素b是否屬于同一組
2:合并元素a和元素b所在組 (將有相同元素的元素 合并為一個(gè)組 )
3:需要初始化一個(gè)數(shù)組存放父節(jié)點(diǎn),其索引值 代表元素
2:并查集的AC代碼(模板`)
/*并查集是一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合(Disjoint Sets)的合并及查詢(xún)問(wèn)題1:查詢(xún)?cè)豠和元素b是否屬于同一組2:合并元素a和元素b所在組 (將有相同元素的元素 合并為一個(gè)組 ) 3:需要初始化一個(gè)數(shù)組存放父節(jié)點(diǎn),其索引值 代表元素 */#include<bits/stdc++.h> using namespace std;int father[100]; int find( int x){while( x != father[x] ){x = father[x];}return x; } void merge(int x,int y) {int a = find(x);//x的根節(jié)點(diǎn)為a int b = find(y);//y的根節(jié)點(diǎn)為bif( a != b )father[b] = a;//那么將b的根節(jié)點(diǎn) 設(shè)為 a }int main() {//初始化: 我們將每一個(gè)結(jié)點(diǎn)的前導(dǎo)結(jié)點(diǎn)設(shè)置為自己,//如果在merge函數(shù)時(shí)未能形成連通,將獨(dú)立成點(diǎn)for( int i = 0; i < 10; i++ ){father[i] = i;}}上方的find函數(shù) 效率不高,當(dāng)處理大數(shù)據(jù)時(shí),使用并查集查找時(shí),如果查找次數(shù)很多,那么使用樸素版的查找方式肯定要超時(shí)。比如,有一百萬(wàn)個(gè)元素,每次都從第一百萬(wàn)個(gè)開(kāi)始找,這樣一次運(yùn)算就是106,如果程序要求查找個(gè)一千萬(wàn)次,這樣下來(lái)就是1013,肯定要出問(wèn)題的。
所以有了壓縮路徑的算法(就是一棵樹(shù)只有葉節(jié)點(diǎn))
int find( int a ){int r=a;while(Father[r]!=r)r=Father[r]; //找到他的前導(dǎo)結(jié)點(diǎn)int i=a,j;while(i!=r){ //路徑壓縮算法j=Father[i]; //記錄x的前導(dǎo)結(jié)點(diǎn)Father[i]=r; //將i的前導(dǎo)結(jié)點(diǎn)設(shè)置為r根節(jié)點(diǎn)i=j;}return r; }如有疑問(wèn) 請(qǐng)留言! 加油陌生的你
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的并查集的相关知识详解 Come baby!!!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 7-8 最优服务次序问题 (10 分)
- 下一篇: 7-3 最小生成树-kruskal (1