题目:
链接:点击打开链接
题意:
有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