Title
Solution
将边权和询问排序,然后用指针扫描,对于新增的点,考虑累计贡献
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define rep(i,x,y) for(register int i=x;i<=y;i++)
using namespace std;
const int N=2e5+10;
struct node{int x,y,z;}a[N];
int T,n,m,q,f[N],size[N]; ll t[N];
struct nodd{int x,y;
}b[N];
inline int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
inline bool cmp(node x,node y){return x.z<y.z;}
inline bool cmpp(nodd x,nodd y){return x.x<y.x;}
int main(){
scanf("%d",&T);
for(int k=1;k<=T;k++){
scanf("%d%d%d",&n,&m,&q);
rep(i,1,m) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
rep(i,1,n) f[i]=i,size[i]=1;
rep(i,1,q) scanf("%d",&b[i].x),b[i].y=i;
sort(a+1,a+m+1,cmp);
sort(b+1,b+q+1,cmpp);
int j=1; ll ans=0;
rep(i,1,q){
while (a[j].z<=b[i].x&&j<=m){
int x=find(a[j].x),y=find(a[j].y);
if (x>y) swap(x,y);
if (x!=y) {
ans+=2ll*size[x]*size[y];
f[x]=y; size[y]+=size[x];
}
j++;
}
t[b[i].y]=ans;
}
rep(i,1,q) printf("%lld\n",t[i]);
}
return 0;
}