洛谷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;
}
posted @ 2020-02-23 18:40  quanjun  阅读(133)  评论(0编辑  收藏  举报