並查集 並查集的刪除操作

2022-09-19 04:15:11 字數 1395 閱讀 3869

描述

一天小\(w\)給學弟們上課,小\(w\)說:注意了,並查集只適合於加的操作,不太方便處理減的操作喲。\(j\)老師聽了後,呵呵了一下。她課後找到小\(w\)說,其實並查集也可以做減的操作的。只看你如何靈活運用了。比如這個題:

給你\(n\)個元素,最開始時分屬於\(n\)個集合,有如下三種操作:

小\(w\)陷入了無盡的思考中.......你能幫幫他嗎?

輸入給出\(n,m\)代表\(n\)個元素,\(m\)個操作,\(1\le n,m\le 10^5\)

輸出查詢的數所在集合有多少個元素以及元素的和。

一道並查集題目。

對於操作\(1\),直接找到兩個數的父親,然後\(father_b=a\)

對於操作\(2\),很明顯,如果移動的數是葉子節點,那麼很簡單,像操作\(1\)一樣就可以了。但是,如果移動的數是父節點甚至根節點,移動乙個數就要改變這棵樹,時間複雜度非常高,不易操作。

對於操作\(3\),要定義兩個陣列儲存。

對於操作\(2\),我們只要滿足所有數都是葉子節點就能保證簡單的移動,怎樣才能滿足這一點呢?

我們可以用一種新的方法——開虛點,也就是說對於每個數\(i\),在開乙個數\(n+i\),並且\(f_i=f_=n+i\),這樣合併和刪除時每個數一定是葉子節點,因為每個數都有乙個父親,如下:

也就是說將\(father_x=b\),將這個數的父親指向集合\(b\),有乙個父親,不存在自己是父節點,來一張圖:

對於操作\(3\),要定義兩個陣列\(tot\)和\(sum\),分別代表這個集合有多少個數以及所有數的和。

輸出查詢的數所在的集合有多少個元素以及元素的和,即\(tot_a\)和\(sum_a\)

注意合併刪除時\(tot\)和\(sum\)陣列的變化,不要打反了。

在題解中\(x\)和\(y\)修改的數,\(a\)和\(b\)代表\(x\)和\(y\)所在集合。

初始化時注意虛點的資料,即\(f_i=f_=n+i\),\(sum_i=sum_=i\),\(tot_i=tot_=1\)

#includeusing namespace std;

const int n=1e7+7;

int f[n],sum[n],tot[n];

int find(int x)

int main()

for(int i=1;i<=m;i++)

}if(flag==2)

}if(flag==3)

}return 0 ;

}

並查集入門(普通並查集 帶刪除並查集 關係並查集)

什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...

並查集 並查集

本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...

可刪除並查集 myf並查集

繼月賽出了道可刪除並查集後,又做了幾道可刪除並查集的題,發現之前的 有點小問題。可刪除並查集的基本原理是設定乙個虛點,也就是說乙個點刪除了,那麼他對應的值就不再是之前的那乙個點,而是變成了其他點。即可刪除並查集通過id對映的關係查詢我的點在 有幾個問題就是初始化時必須要把 n m 個點的父親結點都設...