AcWing 238. 银河英雄传说
原题链接
简单
作者:
捡到一束光
,
2019-12-22 12:00:15
,
所有人可见
,
阅读 1653
维护与祖宗结点的距离
算法详解
/**
* @Author: Wilson79
* @Datetime: 2019年12月22日 星期日 11:43:37
* @Filename: 238.银河英雄传说.cpp
*/
// 用size去维护每个连通块的个数,d[x]表示x到当前祖宗结点的距离,d[x]在find一次后会更新
// 每次把size加到pa上,这样整个pa连通块上的点的d[i],之后更新时都会加上这个size
#include <iostream>
using namespace std;
const int N = 30010;
int p[N], d[N], size[N];
int a, b;
int find(int x) {
if (p[x] != x) {
int root = find(p[x]); // 递归到底
d[x] += d[p[x]]; // 从底往回,更新距离
p[x] = root; // 压缩路径
}
return p[x];
}
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < N; i ++) {
p[i] = i;
size[i] = 1;
d[i] = 0;
}
while(T --) {
char op[2]; // 用scanf读单个字符的巧妙写法
scanf("%s%d%d", op, &a, &b);
if (op[0] == 'M') {
int pa = find(a), pb = find(b);
d[pa] += size[pb]; // 把size加到pa结点即可,这样原pa连通块上的距离在之后find时都会加上这个size
size[pb] += size[pa];
p[pa] = pb;
} else {
int pa = find(a), pb = find(b);
// 必须find一次,才能把d[a],d[b]更新到最新
if (pa != pb) cout << "-1" << endl;
else {
cout << max(abs(d[a] - d[b]) - 1, 0) << endl;
}
}
}
return 0;
}
为什么不是size[pa] += size[pb];
要看先后顺序的
a连在b上面,b是a的父节点了,相当于扩充了b的子节点
mua! (*╯3╰)
%%%
终于理解为什么$else$里也要$find$了
感谢这篇题解~看一眼我就懂了tql啊啊啊啊啊啊
谢谢,刚刚做完这道题觉得缺了点啥,在你这看明白了,赞一个
Thanks♪(・ω・)ノ