題目鏈結:
題目大意:每次指定一塊磚頭,移動磚頭所在堆到另一堆。查詢指定磚頭下面有幾塊磚頭。
解題思路:
【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而言,它們之間必定存在著某種聯絡,因為並查集中的元素均...