# 并查集
# 学习资源
# ITMO Academy: pilot course (opens new window)
来自Codeforces EDU。包括视频教程、图文教程和18道练习题
# 练习题
# BS - Graph Weight Queries (opens new window)
提示一
离线查询。
提示二
查询和边都按照权重从小到大排序,逐步向图中添加边。
参考代码(C++)
#include "solution.hpp"
using namespace std;
class Solution {
vector<int> p, sz;
int find(int u) {
return p[u] == u ? u : p[u] = find(p[u]);
}
void connect(int u, int v) {
int pu = find(u), pv = find(v);
if (pu == pv)
return;
if (sz[pu] >= sz[pv]) {
p[pv] = pu;
sz[pu] += sz[pv];
} else {
p[pu] = pv;
sz[pv] += sz[pu];
}
}
public:
int solve(vector<vector<int>>& edges, vector<vector<int>>& queries) {
int n = edges.size();
p = vector<int>(n << 1);
sz = vector<int>(n << 1, 1);
for (int i = 0; i < (n << 1); ++i)
p[i] = i;
auto cmp = [](vector<int> &a, vector<int> &b){
return a[2] < b[2];
};
sort(edges.begin(), edges.end(), cmp);
sort(queries.begin(), queries.end(), cmp);
int idx = 0, ans = 0;
for (auto q : queries) {
while (idx < n && edges[idx][2] <= q[2]) {
connect(edges[idx][0], edges[idx][1]);
idx++;
}
if (find(q[0]) == find(q[1]))
ans++;
}
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
在线解法
本题同样可以在线求解。我们需要分两步进行。首先,求出最大值意义下的最小生成树。然后,对于这棵最小生成树,用倍增法求LCA;在预处理的过程中,除了得到第级的祖先,同时求得到这一祖先的路径上的最大权重。对于每一个查询,首先求出LCA,然后让和分别上移到LCA位置,记录路径上的最大权重。将这个最大权重与查询的限制条件进行比较即可。