洛谷P4185 [USACO18JAN]MooTube G 题解 并查集
题目链接:https://www.luogu.com.cn/problem/P4185
解题思路完全参考自 cjx大佬的博客
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct Edge {
int u, v, w;
} edge[maxn];
struct Query {
int k, v, id, ans;
} query[maxn];
int n, q, f[maxn], sz[maxn];
void init() {
for (int i = 1; i <= n; i ++) f[i] = i, sz[i] = 1;
}
int Find(int x) {
return x == f[x] ? x : f[x] = Find(f[x]);
}
void Union(int x, int y) {
int a = Find(x), b = Find(y);
if (a != b) {
f[b] = f[x] = f[y] = a;
sz[a] += sz[b];
}
}
bool cmp1(Edge a, Edge b) {
return a.w > b.w;
}
bool cmp2(Query a, Query b) {
return a.k > b.k;
}
bool cmp3(Query a, Query b) {
return a.id < b.id;
}
int main() {
scanf("%d%d", &n, &q);
init();
for (int i = 0; i < n-1; i ++)
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
for (int i = 0; i < q; i ++) {
scanf("%d%d", &query[i].k, &query[i].v);
query[i].id = i;
}
sort(edge, edge+n-1, cmp1);
sort(query, query+q, cmp2);
int j = 0;
for (int i = 0; i < q; i ++) {
while (j < n-1 && edge[j].w >= query[i].k) {
Union(edge[j].u, edge[j].v);
j ++;
}
query[i].ans = sz[Find(query[i].v)];
}
sort(query, query+q, cmp3);
for (int i = 0; i < q; i ++)
cout << query[i].ans-1 << endl;
return 0;
}