题目链接:http://acm.hust.edu.cn/vjudge/problem/36132
大意:给出n个结点,一系列操作。对于操作I,输入u,v,把u的父结点设为v,距离为|u-v|mod1000;对于操作E,输入u,输出u到根结点的距离。
思路:两个操作正好对应了并查集的合并和查找,对于操作I,由于v没有父结点,直接令pre[u] = v即可;对于操作E,由于根节点是动态变化的,所以要先更新再查询。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 2e4 + 5;
int n, pre[maxn], dist[maxn];
int find(int x)
{
if (pre[x] == x) return pre[x];
int y = pre[x];
pre[x] = find(pre[x]);
dist[x] += dist[y];
return pre[x];
}
int main()
{
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
memset(dist, 0, sizeof dist);
for(int i = 1; i <= n; i++) pre[i] = i;
char s[2];
while(scanf("%s",s) && s[0] != 'O') {
if (s[0] == 'E') {
int x;
scanf("%d",&x);
find(x);
printf("%d\n",dist[x]);
}
else {
int a,b;
scanf("%d%d",&a,&b);
pre[a] = b;
dist[a] = abs(a-b) % 1000;
}
}
}
}

本文通过一道编程题解析并查集算法的应用。题目要求处理结点间的操作,包括设置父子关系及查询路径长度。文章提供了完整的C++代码实现,并详细解释了如何利用并查集进行动态维护。
11万+

被折叠的 条评论
为什么被折叠?



