題目:
話說上次偉神和肖神去買東西,由於偉神身材瘦削,體力不支所以沒能把肖神想要的東西都揹回來,最後還是在基地同學的幫助下,才勉強揹回了價值最大的物品。對於這個事情,肖神非常不滿,於是,肖神為偉神制定了一套鍛鍊身體的方案。肖神從網上網購了 n 個石塊(1<=n<=30000)。這些石塊的編號從1到n不等。肖神接著會讓偉神做 p 個動作(1<=p<=100000)。這些動作包含兩種:堆放和計算數量。
(1)若肖神讓偉神堆放石塊,她就會喊「a x y」,偉神必須把包含y石塊的一摞石塊疊放在包含x石塊的一摞石塊上。
(2)若肖神讓偉神計算數量,她就會喊「b x」,偉神就會數x石塊下有幾個石塊。
輸入的第一行有乙個整數p,表示肖神會讓偉神做出p個動作。從第二行開始,每一行都會進行乙個動作。每個石塊的編號是從1到30000以內的任意乙個數字,是不確定的。
請輸出每次計算數量操作的結果。
6a 6 1
b 1a 4 2
a 6 2
b 3b 4
102
小天
題解:由於並查集記錄的通常是結點與樹根的關係,所以直接記錄結點其下節點數目的方式難以實現,因此可以通過記錄節點其上節點數目與整棵樹的結點總數目間接求解
1.為了便於解題,首先建立乙個結構體,結構體中的元素需要記錄結點的父節點,結點所在樹的結點總數,疊放在結點之上的結點數目,初始化時注意賦值
2.對每組需疊加的箱子進行並操作,並操作的時候注意更新結點上記錄的資料
3.當遇到詢問操作的時候,先找到這個結點的根節點,再由式子: 樹的結點總數目 - 被詢問結點上面的結點數目 - 1 得到答案
**:#include#include#define n 30010
typedef struct mystruct
point;
point point[n];
int find_parent(int p)
else//路徑壓縮 }
void makeup(int a,int b)//合併操作
}int main()
{ int n,p;//石塊數和運算元
int i;
int a,b;//合併操作的兩個堆
int k;//問k下面有多少塊石塊
int ans;
char temp;
for ( i = 1; i
疊積木(加權並查集)
題目描述 約翰和貝西在疊積木。共有30000塊積木,編號為1到30000。一開始,這些積木放在地上,自然地分成n堆。貝西接受約翰的指示,把一些積木疊在另一些積木的上面。一旦兩塊積木相疊,彼此就再也不會分開了,所以最後疊在一起的積木會越來越高。約翰讓貝西依次執行p條操作,操作分為兩種 第一種是移動操作...
luoguP2342 疊積木(並查集)
傳送門 up i 表示乙個木塊上面有多少個 all i 表示整個連通塊內有多少個 那麼 乙個木塊下面的木塊個數為 all root i up i 1 注意 up i 可以在 find 函式中維護,而 all i 不好維護,那麼我們只需要祖先節點的 all i 表示整個連通塊內木塊的數目即可 合併時也...
並查集 並查集
本文參考了 挑戰程式設計競賽 和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 ...