HDU 2818 向量並查集

2022-07-04 12:42:11 字數 1012 閱讀 2032

題目鏈結

題目大意:每次指定一塊磚頭,移動磚頭所在堆到另一堆。查詢指定磚頭下面有幾塊磚頭。

解題思路

【hdu資料有問題】,資料從0開始,且給定n塊磚頭(比如1000),資料會有第1005塊磚頭,導致訪問越界。

【解決方案】,並查集初始化範圍改為0~maxn(30005)

由於只給定一塊磚頭,卻要移動所在堆。所以需要並查集維護所在堆。

p[x]=y,即x所在堆的堆底是y,注意此時並查集是有方向的。

用under[x]維護x下面有幾塊磚頭,sum[x]維護x所在堆一共有幾塊磚頭。

對於移動x堆到y堆,首先對x和y的堆底兩點處理,合併後,x堆、y堆所有點的堆底都指向y堆的堆底:

①獲取x和y所在堆的堆底,即x=find(x),y=find(y)

②under[x]=sum[y],即合併後,x堆下面有y堆總個數

③sum[y]+=sum[x],由於合併後,兩堆結點在路徑壓縮時會集體更新,所以這裡只要令sum[y]=兩堆和就可以了。

③f[x]=y,讓x堆的堆底都指向y堆堆底。

路徑壓縮部分:

①under[x]+=under[f[x]],即原x堆堆底以上的under,全部加上堆底under(堆底已經被手動更新)。

②f[x]=find(f[x]),堆底以上的指向更新。

#include "

cstdio

"#define maxn 30005

intf[maxn],under[maxn],sum[maxn];

int find(int

x)

else

returnx;}

void union(int x,inty)}

intmain()

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

else

}}

hdu2818與hdu3635 (帶權並查集)

約翰正在玩積木。有n個block 1 n 30000 編號為1 n 最初有n根樁,每根樁包含乙個塊。然後john做一些運算p次 1 p 1000000 有兩種操作 m x y 把包含x塊的整個堆放到包含y塊的堆上,如果x和y在同一堆上,就忽略這個命令。c x計算方塊x下的方塊數 要求您找出每個c操作...

HDU3938 並查集 並查集

先按邊權值排個序,每次加入一條邊,用並查集,關鍵看懂題。include include include include using namespace std const int maxn 10010 int n,m,q struct edge edges maxn 5 inline int cmp...

hdu 3038 擴充套件並查集 向量思想

題意 給出區間 1,n 下面有m組資料,l r v區間 l,r 之和為v,每輸入一組資料,判斷此組條件是否與前面衝突 最後輸出與前面衝突的資料的個數.看大佬的部落格 向量偏移好秀啊,可以直接找到根節點和子節點的關係。對於集合裡的任意兩個元素x,y而言,它們之間必定存在著某種聯絡,因為並查集中的元素均...