题目:
链接:点击打开链接
题意:
有N个积木,1到N编号。进行一些操作P次,M:X Y把X积木放到Y的上面,如果X和Y相等请忽略。C:X 计算X积木下的积木数目。
思路:
带权并查集的题目,定义数组sum[i]表示i积木下面积木的数目。遇到操作M,就把X和Y合并到同一个集合中。我们视每个结点为1个 Pile,其中rank[i]就表示每个Pile处的积木的个数,Initially, there are N piles, and each pile contains one block.所以,rank[]的初始值应该是1。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 30030;
int root[N];
int sum[N],rank[N];
int q;
int findset(int x)
{
if(x == root[x])
return x;
int temp = findset(root[x]);
sum[x] += sum[root[x]];
return root[x] = temp;
}
void mergeset(int x,int y)
{
int fx = findset(x);
int fy = findset(y);
if(fx == fy)
return ;
root[fx] = fy;
sum[fx] += rank[fy];//sum
rank[fy] += rank[fx];//每进行一次M操作,rank的值都要更新。
}
void init()
{
for(int i=0; i<=30000; i++)
{
root[i] = i;
rank[i] = 1;
sum[i] = 0;
}
}
int main()
{
//freopen("input.txt","r",stdin);
char ch;
int x,y,z;
while(scanf("%d",&q) != EOF)
{
init();
getchar();
while(q--)
{
scanf("%c",&ch);
getchar();
if(ch == 'M')
{
scanf("%d%d",&x,&y);
mergeset(x,y);
}
else
{
scanf("%d",&z);
findset(z);
printf("%d\n",sum[z]);
}
getchar();
}
}
return 0;
}
---------------------------------------------------------------
战斗,从不退缩;奋斗,永不停歇~~~~~~~~
hdu 2818 Building Block(带权并查集),布布扣,bubuko.com
hdu 2818 Building Block(带权并查集)
原文:http://blog.csdn.net/u013147615/article/details/30506647