[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;
}