[USACO18JAN]MooTube G

题目链接

感觉排个序会非常好做,就能省了很多事
但是询问是不讲顺序的,那就离线一下

#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 100005

int f[MAXN],size[MAXN];

int find(int x) {
    return f[x]==x ? x : f[x] = find(f[x]);
}

inline void merge(int x,int y) {
    int fx = find(x), fy = find(y);
    if(fx==fy) return;
    if(size[fx]<size[fy]) f[fx] = fy,size[fy] += size[fx];
    else f[fy] = fx,size[fx] += size[fy];
}

struct edge {
    int u,v,w;
    inline bool operator < (const edge& e) const {
        return w > e.w;
    }
} E[MAXN];

struct query {
    int k,v,cnt,ans;
} A[MAXN];

inline bool cmp1(query a,query b) {
    return a.k > b.k;
}
inline bool cmp2(query a,query b) {
    return a.cnt < b.cnt;
}

int N,Q;

int main() {

    cin >> N >> Q;
    for(int i=1;i<=N;++i) {
        f[i] = i; size[i] = 1;
    }

    for(int i=1;i<N;++i) {
        cin >> E[i].u >> E[i].v >> E[i].w;
    }
    sort(E+1,E+N);

    for(int i=1;i<=Q;++i) {
        cin >> A[i].k >> A[i].v;
        A[i].cnt = i;
    }
    sort(A+1,A+1+Q,cmp1);
    int p = 0;

    for(int i=1;i<=Q;++i) {
        while(p<N&&E[p+1].w>=A[i].k) {
            p++; merge(E[p].u,E[p].v);
        }
        A[i].ans = size[find(A[i].v)] - 1;
    }
    sort(A+1,A+1+Q,cmp2);
    
    for(int i=1;i<=Q;++i) cout << A[i].ans << '\n';
    return 0;
}
posted @ 2021-10-21 15:22  Neworld1111  阅读(338)  评论(0编辑  收藏  举报