您的位置:首页 > 产品设计 > UI/UE

hdu 2818 Building Block(并查集)

2015-03-17 18:08 369 查看
每次总有新领悟。。

认为没堆最底层为祖先。

关于findset是怎么维护的,这次又好好理解了一下,这道题是每次更新x和x的上一层的结点,自底层向上(从祖先一层一层到本身)。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<iomanip>
#include<climits>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<vector>
#include<stack>
#include<set>
#define INF 1e7
#define MAXN 10010
#define maxn 1000010
#define Mod 1000007
#define N 1010
using namespace std;
typedef long long LL;

int n, m;
int fa[333333];
int num[333333];
int un[333333];

//取每一堆最底部的为祖先
//从祖先向下一层一层更新
int findset(int x)
{
if (x == fa[x]) return x;
int tmp = findset(fa[x]);
un[x] += un[fa[x]];
fa[x] = tmp;
return fa[x];
}

void merg(int a, int b)
{
int x = findset(a);
int y = findset(b);
if (x != y) {
un[x] = num[y];
num[y] += num[x];
fa[x] = y;
}
}

int main()
{
int a, b;
char ch;
while (~scanf("%d",&n)) {
getchar();
for (int i = 0; i <= n; ++i)
fa[i] = i, num[i] = 1,un[i] = 0;

for (int i = 0; i < n; ++i) {
scanf("%c ",&ch);
if (ch == 'M') {
scanf("%d%d",&a,&b);
getchar();
merg(a, b);
}
else {
scanf("%d",&a);
getchar();
findset(a);
printf("%d\n",un[a]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: