类似于NOI2018d1t1的离线做法,把询问存下来,排个序,然后倒着给并查集加边,每次询问并查集联通块大小
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define pa pair<int,int> 4 using namespace std; 5 const int maxn=100010; 6 7 inline ll rd(){ 8 ll x=0;char c=getchar(); 9 while(c<'0'||c>'9') c=getchar(); 10 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 11 return x; 12 } 13 14 struct Edge{ 15 int a,b,l; 16 }eg[maxn],que[maxn]; 17 int N,M; 18 int fa[maxn],siz[maxn],ans[maxn]; 19 20 inline bool cmp(Edge a,Edge b){ 21 return a.l>b.l; 22 } 23 24 int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);} 25 inline void add(int a,int b){ 26 int x=getf(a),y=getf(b); 27 fa[x]=y;siz[y]+=siz[x]; 28 } 29 30 int main(){ 31 int i,j,k; 32 N=rd(),M=rd(); 33 for(i=1;i<N;i++){ 34 eg[i].a=rd(),eg[i].b=rd(),eg[i].l=rd(); 35 }for(i=1;i<=M;i++){ 36 que[i].l=rd(),que[i].a=rd(); 37 que[i].b=i; 38 } 39 for(i=1;i<=N;i++) fa[i]=i,siz[i]=1; 40 sort(eg+1,eg+N,cmp);sort(que+1,que+M+1,cmp); 41 for(i=1,j=1;i<=M;i++){ 42 for(;j<N&&eg[j].l>=que[i].l;j++) add(eg[j].a,eg[j].b); 43 ans[que[i].b]=siz[getf(que[i].a)]; 44 } 45 for(i=1;i<=M;i++) printf("%d\n",ans[i]-1); 46 }