一、問題描述 題目鏈結
有n個節點(1≤n≤100000),進行如下兩種操作:
(1) m a b, 把a、b合併
(2)s a, 把a分離出來
進行m(1≤m≤1000000)次操作,問最後有幾個組?
二、解題思路
用並查集來實現,我們都知道並查集的合併操作很容易實現,而從集合中移出乙個元素卻很難。
這樣想,移出元素相當於建立乙個新的集合,我們只需將其指向乙個獨立的節點。這對於葉子節點容易操作,但如果是中間節點(或根節點),則會導致原集合斷開。
我們將節點編號為0~n-1,將他們的根節點初始化為n~2n-1,這樣保證了節點0~n-1都是葉子節點。同時將所有的移出節點分別指向2n~2n+m。最後查詢0~n-1所在的不同的集合數。
三、**實現
1 #include2 #include3 #include4 #include5 #include6using
namespace
std;78
const
int maxn = 100000 + 10;9
const
int maxk = 1000000 + 10;10
intn, qcnt;
11int fa[2 * maxn +maxk];
12bool vis[2 * maxn + maxk]; //
注意陣列範圍,2n+最大查詢數
1314
void
init()
1522
23int findset(int
x)24
2930
void unite(int x, int
y)31
3738
intmain()
3955
if (order[0] == 's'
)5659}
60int ans = 0;61
for (int i = 0; i < n; i++)
6269
}70 printf("
case #%d: %d\n
", ++kase, ans);71}
72 }
並查集 並查集的刪除操作
描述 一天小 w 給學弟們上課,小 w 說 注意了,並查集只適合於加的操作,不太方便處理減的操作喲。j 老師聽了後,呵呵了一下。她課後找到小 w 說,其實並查集也可以做減的操作的。只看你如何靈活運用了。比如這個題 給你 n 個元素,最開始時分屬於 n 個集合,有如下三種操作 小 w 陷入了無盡的思考...
可刪除並查集 myf並查集
繼月賽出了道可刪除並查集後,又做了幾道可刪除並查集的題,發現之前的 有點小問題。可刪除並查集的基本原理是設定乙個虛點,也就是說乙個點刪除了,那麼他對應的值就不再是之前的那乙個點,而是變成了其他點。即可刪除並查集通過id對映的關係查詢我的點在 有幾個問題就是初始化時必須要把 n m 個點的父親結點都設...
並查集入門(普通並查集 帶刪除並查集 關係並查集)
什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...