帶權並查集,主要是來處理集合元素與元素之間的關係,或者說元素與元素連線之間的權值,
板子是這樣的
int find(int x) {
if (x == root[x]) return x;
else {
int t = find(root[x]);
sum[x] += sum[root[x]];
root[x]=t;
return root[x];
}
}
sum[i]裏面用來存放i結點到根節點的權值和,emmm,說這麼多看例題。這個題特別坑人,寫的時候TLE無數次,最後緩了過來,我模板寫錯了。。。。。。。。
poj 1988Cube Stacking
大意 是移動箱子,剛開始每個箱子算一列,有兩種操作,m x,y,將x列的箱子放y上。c x,查詢x這個箱子,下面有多少個箱子。
sum 是計算這列一共有多個箱子,d[i]計算i上面有多少個箱子。sum[find(x)]-d[i]-1,就是輸出的結果
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int root[30009],mmax,sum[30009],d[30009];
int find(int x)
{
if(x==root[x])
return x;
int fx=find(root[x]);
d[x]+=d[root[x]];
root[x]=fx;
return root[x];
}
void join(int x,int y)
{
int xx=find(x);
int yy=find(y);
if(xx!=yy)
{ root[yy]=xx;
d[yy]=sum[xx];
sum[xx]+=sum[yy];
}
}
int main(){
int t,n,mm;
scanf("%d",&t);
char ch[3];
for(int i=1;i<=30000;i++)
{
root[i]=i;
d[i]=0;
sum[i]=1;
}
while(t--)
{ int x,y;
scanf("%s",ch);
if(ch[0]=='M')
{
scanf("%d %d",&x,&y);
join(x,y);
}
else if(ch[0]=='C')
{ scanf("%d",&x);
printf("%d\n",sum[find(x)]-d[x]-1);
}
}
return 0;
}