合并完一共有几块
同样合并完之后。运行下面这段程序:
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
// 五个人:0 阿岚、1 小满、2 阿泰、3 南风、4 北辰
const vector<string> NAMES = {"阿岚", "小满", "阿泰", "南风", "北辰"};
// 四段关系(无向):阿岚-小满、阿岚-阿泰、小满-阿泰、阿泰-南风
const vector<pair<int, int>> EDGES = {{0, 1}, {0, 2}, {1, 2}, {2, 3}};
int id_of(const string& name) {
for (int i = 0; i < (int)NAMES.size(); i++) {
if (NAMES[i] == name) return i;
}
return -1;
}
vector<int> init_uf() {
vector<int> p(NAMES.size());
for (int i = 0; i < (int)p.size(); i++) p[i] = i; // 每人先自成一块
return p;
}
int find_root(vector<int>& p, int x) {
while (p[x] != x) {
p[x] = p[p[x]]; // 路径压缩:顺手往上挂一层
x = p[x];
}
return x;
}
void unite(vector<int>& p, int a, int b) {
int ra = find_root(p, a), rb = find_root(p, b);
if (ra != rb) p[ra] = rb;
}
int main() {
auto p = init_uf();
for (auto [a, b] : EDGES) unite(p, a, b);
vector<bool> is_root(NAMES.size(), false);
for (int i = 0; i < (int)NAMES.size(); i++) is_root[find_root(p, i)] = true;
int k = 0;
for (bool r : is_root) k += r;
cout << k << endl;
}
(本题用 g++ -std=c++17 -O0 编译。)
全部评论