标签:class ++ str 路径 定义 += void mp3 pre
题目大意:给你一棵边权树,定义两点间距离为它们唯一路径上的最小路权,求与某点距离不大于K(k为已知)的点的数量
带权并查集维护集合内元素总数
路和问题 都按权值大到小排序,枚举问题, 建权值不小于K的边,并查集维护连通性,求集合元素内总数即可
1 #include <bits/stdc++.h> 2 #define N 200100 3 #define inf 0x3f3f3f3f 4 using namespace std; 5 6 int n,q,cnt; 7 int fa[N],f[N]; 8 struct EDGE{ 9 int x,y,w; 10 }edge[N]; 11 struct QUES{ 12 int k,v,id,ans; 13 }ques[N]; 14 15 int cmp1(EDGE s1,EDGE s2) {return s1.w>s2.w;} 16 int cmp2(QUES s1,QUES s2) {return s1.k>s2.k;} 17 int cmp3(QUES s1,QUES s2) {return s1.id<s2.id;} 18 void edge_add(int x,int y,int z) 19 { 20 cnt++; 21 edge[cnt].x=x; 22 edge[cnt].y=y; 23 edge[cnt].w=z; 24 } 25 int find_fa(int x) 26 { 27 int fx=x; 28 while(fx!=fa[fx]) {fx=fa[fx];} 29 while(fa[x]!=fx) 30 { 31 int pr=fa[x]; 32 f[pr]-=f[x]; 33 fa[x]=fx; 34 x=pr; 35 } 36 return fx; 37 } 38 void comb(int x,int y) 39 { 40 int fx=find_fa(x); 41 int fy=find_fa(y); 42 fa[fy]=fx; 43 f[fx]+=f[fy]; 44 } 45 46 int main() 47 { 48 scanf("%d%d",&n,&q); 49 for(int i=1;i<n;i++) 50 { 51 int x,y,z; 52 scanf("%d%d%d",&x,&y,&z); 53 edge_add(x,y,z); 54 } 55 sort(edge+1,edge+n,cmp1); 56 for(int i=1;i<=q;i++) 57 { 58 int x,y; 59 scanf("%d%d",&x,&y); 60 ques[i].k=x; 61 ques[i].v=y; 62 ques[i].id=i; 63 } 64 sort(ques+1,ques+q+1,cmp2); 65 for(int i=1;i<=n;i++) 66 { 67 fa[i]=i; 68 f[i]=1; 69 } 70 int j=1; 71 for(int i=1;i<=q;i++) 72 { 73 while(edge[j].w>=ques[i].k) 74 { 75 comb(edge[j].x,edge[j].y); 76 j++; 77 } 78 int fv=find_fa(ques[i].v); 79 ques[i].ans=f[fv]-1; 80 } 81 sort(ques+1,ques+q+1,cmp3); 82 for(int i=1;i<=q;i++) 83 { 84 printf("%d\n",ques[i].ans); 85 } 86 return 0; 87 }
[USACO18JAN] MooTube (并查集 -> 维护连通性)
标签:class ++ str 路径 定义 += void mp3 pre
原文地址:https://www.cnblogs.com/guapisolo/p/9696881.html