亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

c語言數據結構之并查集 總結

2020-05-23 13:30:21
字體:
來源:轉載
供稿:網友

并查集(Union-Find Set):

一種用于管理分組的數據結構。它具備兩個操作:(1)查詢元素a和元素b是否為同一組 (2) 將元素a和b合并為同一組。

注意:并查集不能將在同一組的元素拆分為兩組。

并查集的實現:

用樹來實現。

c語言,數據結構,并查集

使用樹形結構來表示以后,每一組都對應一棵樹,然而我們就可以將這個問題轉化為樹的問題了,我們看兩個元素是否為一組我們只要看這兩個元素的根是否一致。顯然,使用樹形結構將問題簡單化了。合并時是我們只需要將一組的根與另一組的根相連即可。

并查集的核心在于,一棵樹的所有節點根節點都為一個節點。使用Find函數查詢時,也是查詢到這個節點的根節點。

一行并查集:

int find(int x){ return p[x]==x? x:find(p[x]); //x的父節點保存在p[x]中,如果沒有父節點則p[x]=x。}

實現:

int node[i]; //每個節點  //初始化n個節點 void Init(int n){  for(int i = 0; i < n; i++){  node[i] = i;  } } //查找當前元素所在樹的根節點(代表元素) int find(int x){  if(x == node[x])  return x;  return find(node[x]); } //合并元素x, y所處的集合 void Unite(int x, int y){  //查找到x,y的根節點  x = find(x);  y = find(y);  if(x == y)  return ;  //將x的根節點與y的根節點相連  node[x] = y; } //判斷x,y是屬于同一個集合 bool same(int x, int y){  return find(x) == find(y)

并查集的路徑壓縮:

在特殊情況下,這棵樹是一條長長的樹鏈,設鏈的最后一個結點為x,則每次執行find(x)都會遍歷整條鏈。效率十分的地下。 改進方法很簡單,只要把遍歷過的結點都改成根的子結點,后面的查詢就會變的快很多。

c語言,數據結構,并查集

并查集的復雜度

加入這兩個優化之后,并查集的效率就非常高。對n個元素的并查集操作一次的復雜度是: O(α(n))。這里,α(n)是阿克曼(Ackermann)函數的反函數。效率要高于O(log n)。

不過這里O(α(n))是平均復雜度。也就是說,多次操作之后平均復雜度為O(α(n)),換而言之,并不是每一次操作都滿足O(α(n))。

路徑壓縮后的優化代碼:

 int node[i]; //每個節點  int rank[i]; //樹的高度   //初始化n個節點  void Init(int n){  for(int i = 0; i < n; i++){   node[i] = i;   rank[i] = 0;  }  }  //查找當前元素所在樹的根節點(代表元素)  int find(int x){  if(x == node[x])   return x;  return node[x] = find(node[x]); //在第一次查找時,將節點直連到根節點  }  //合并元素x, y所處的集合  void Unite(int x, int y){  //查找到x,y的根節點  x = find(x);  y = find(y);  if(x == y)   return ;  //判斷兩棵樹的高度,然后在決定誰為子樹  if(rank[x] < rank[y]){   node[x] = y;  }else{   node[y] = x;   if(rank[x] == rank[y]) rank[x]++:  }  }  //判斷x,y是屬于同一個集合  bool same(int x, int y){  return find(x) == find(y);  } 

實例分析:

題目:部落

在一個社區里,每個人都有自己的小圈子,還可能同時屬于很多不同的朋友圈。我們認為朋友的朋友都算在一個部落里,于是要請你統計一下,在一個給定社區中,到底有多少個互不相交的部落?并且檢查任意兩個人是否屬于同一個部落。

輸入格式:

輸入在第一行給出一個正整數N(<= 104),是已知小圈子的個數。隨后N行,每行按下列格式給出一個小圈子里的人:

K P[1] P[2] ... P[K]

其中K是小圈子里的人數,P[i](i=1, .., K)是小圈子里每個人的編號。這里所有人的編號從1開始連續編號,最大編號不會超過104。

之后一行給出一個非負整數Q(<= 104),是查詢次數。隨后Q行,每行給出一對被查詢的人的編號。

輸出格式:

首先在一行中輸出這個社區的總人數、以及互不相交的部落的個數。隨后對每一次查詢,如果他們屬于同一個部落,則在一行中輸出“Y”,否則輸出“N”。

輸入樣例:
4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7

輸出樣例:

10 2
Y
N

分析:典型并查集問題。

一個部落對應一個集合。 根節點數量等于部落數量。
并查集把每個部落的人連起來,記錄哪些人出現過,枚舉標號10000,找出有多少人和部落,查詢并查集維護。

源碼分析:

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;int pre[10005];int f[10005]; void init() { //初始化父集合pre[10005],以及出現的標志數組f[10005]	for(int i=0; i<10004; i++)		pre[i]=i, f[i]=0;} int find(int x) { //并查集查找根節點的 遞歸程序	return pre[x]==x? x : pre[x]=find(pre[x]);} int main(){	init();	int n,q,k,a,b;	cin>>n;	for(int i=0; i<n; i++) {		cin>>k>>a;		f[a]=1;		for(int j=1; j<k; j++) {			cin>>b;			f[b]=1;			int x=find(a);			int y=find(b);			if(x!=y) pre[x]=y;		}	}	int cnt=0,tot=0; //cnt為所有人數 tot為部落數量	for(int i=0; i<10004; i++) {		if(f[i] == 1) { //如果標志為1 則說明出現過,cnt加一			cnt++;			if(pre[i]==i) tot++; //如果下標為本身 說明其為根節點 根節點數量為部落的數量		}	}	cout<<cnt<<" "<<tot<<endl;	cin>>q;	for(int i=0; i<q; i++) {		cin>>a>>b;		if(find(a) == find(b)) //若兩參數 有同一根節點 說明為一個部落。			cout<<"Y"<<endl;		else cout<<"N"<<endl;	}	return 0;}

好了,這篇文章就介紹到這了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产日韩欧美在线动漫| 亚洲国产成人久久综合| 欧美巨乳在线观看| 91色精品视频在线| 国产欧美在线视频| 亚洲日韩欧美视频| 草民午夜欧美限制a级福利片| 亚洲精品资源在线| 欧美一区二区三区四区在线| 欧美性生活大片免费观看网址| 91社影院在线观看| 日韩欧美高清视频| 51ⅴ精品国产91久久久久久| 国产一区二区三区网站| 欧美超级乱淫片喷水| 国产成人福利网站| 日本精品久久电影| 国产精品劲爆视频| 日韩成人高清在线| 日日骚久久av| 美日韩精品视频免费看| 91国语精品自产拍在线观看性色| 亚洲影院色无极综合| 欧美激情亚洲自拍| 欧美在线视频免费观看| 一区二区欧美亚洲| 91九色蝌蚪国产| 亚洲欧美日韩精品久久| 国产精品激情av在线播放| 亚洲欧美国产一本综合首页| 国产日产欧美a一级在线| 超碰精品一区二区三区乱码| 国内精品一区二区三区| 在线观看不卡av| 久久91亚洲精品中文字幕奶水| 日韩在线观看你懂的| 欧美美最猛性xxxxxx| 欧美人与物videos| 精品久久中文字幕久久av| 国产福利视频一区二区| 狠狠躁天天躁日日躁欧美| 91嫩草在线视频| 欧美日韩在线视频一区| 国产精品久久久久久久久久久久久久| 亚洲精品日韩在线| 久久久久久亚洲精品| 国产精品成久久久久三级| 亚洲第一视频在线观看| 亚洲欧美另类在线观看| 久色乳综合思思在线视频| 色老头一区二区三区在线观看| 日韩av综合中文字幕| 亚洲人成亚洲人成在线观看| 日韩精品一二三四区| 国产亚洲精品激情久久| 成人福利网站在线观看11| 91在线观看免费高清完整版在线观看| 亚洲香蕉成视频在线观看| 国产精品香蕉在线观看| 国产一区二区三区欧美| 色婷婷综合久久久久| 国产一区二区三区丝袜| 精品福利视频导航| 欧美日韩成人免费| 国产精品入口夜色视频大尺度| 久久国产精品久久久久久久久久| 亚洲深夜福利网站| 国产精品嫩草影院久久久| 国产一区av在线| 国产成人精品一区| 国语自产偷拍精品视频偷| 精品人伦一区二区三区蜜桃网站| 日韩av免费在线| 欧美日韩在线免费观看| 国产精品1区2区在线观看| 性欧美暴力猛交69hd| 2019av中文字幕| 大伊人狠狠躁夜夜躁av一区| 81精品国产乱码久久久久久| 日韩欧美成人精品| 久久这里只有精品视频首页| 国产日本欧美一区| 亚洲精品国产精品自产a区红杏吧| 性欧美办公室18xxxxhd| 久久综合伊人77777蜜臀| 久久福利网址导航| 日韩欧美精品免费在线| 国产日本欧美一区二区三区在线| 亚洲国产美女久久久久| 成人天堂噜噜噜| 欧美成人激情在线| 色偷偷av一区二区三区| 国产丝袜高跟一区| 成人a免费视频| 日韩在线视频线视频免费网站| 色哟哟网站入口亚洲精品| 国产脚交av在线一区二区| 欧美日韩国产一区中文午夜| 欧美资源在线观看| 日韩美女在线看| 精品久久久久久久久久久久久| 欧美激情综合色综合啪啪五月| 国产精品av免费在线观看| 欧美激情欧美激情在线五月| 欧美精品免费在线观看| 中文字幕亚洲第一| 成人乱色短篇合集| 亚洲free性xxxx护士hd| 91极品视频在线| 久久精品视频在线观看| 一区二区三区回区在观看免费视频| 97在线视频免费播放| 欧美激情精品久久久久久大尺度| 九九热在线精品视频| 欧美午夜视频一区二区| 成人国产精品av| 亚洲的天堂在线中文字幕| 国产精品久久久亚洲| 日韩精品在线观看视频| 日韩av片电影专区| 久久久久久国产三级电影| 日本午夜人人精品| 影音先锋欧美精品| 久久久免费精品视频| 另类视频在线观看| 国产精自产拍久久久久久蜜| 在线日韩精品视频| 亚洲美女视频网| 中文字幕不卡av| 久久成年人视频| 欧美华人在线视频| 最近2019中文字幕一页二页| 奇米4444一区二区三区| 亚洲欧洲美洲在线综合| 狠狠色噜噜狠狠狠狠97| 国产精欧美一区二区三区| 国产自摸综合网| 亚洲一区美女视频在线观看免费| 成人春色激情网| 国产精品视频中文字幕91| 久久精品久久久久久国产 免费| 国产成人拍精品视频午夜网站| 国产精品久久久久久亚洲调教| 国精产品一区一区三区有限在线| 国产精品96久久久久久| 超碰91人人草人人干| 91成人精品网站| 欧美日韩国产一区二区三区| 九九精品在线播放| 亚洲欧美日韩精品| www.xxxx欧美| 欧美激情精品久久久久久| 国产精品久久久久久超碰| 91wwwcom在线观看| 欧美一级黑人aaaaaaa做受| 成人一区二区电影| 91在线观看免费高清完整版在线观看| 精品视频一区在线视频| 精品性高朝久久久久久久| 欧美黑人狂野猛交老妇| 亚洲欧美国产va在线影院| 美女少妇精品视频| 欧美午夜精品久久久久久浪潮| 精品国产999|