q次询问,每次求出边长大于k构成图中能两两互达的点的对数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
const int N=2e5+7;
int fa[N],sz[N];
struct E
{
int x,y,z;
}e[N];
struct Q
{
int id,k;
LL ans;
}q[N];
bool cmp_z(E a,E b)
{
return a.z>b.z;
}
bool cmp_k(Q a,Q b)
{
return a.k>b.k;
}
bool cmp_id(Q a,Q b)
{
return a.id<b.id;
}
int f(int x)
{
return fa[x]==x?x:fa[x]=f(fa[x]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m,p;
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)
{
fa[i]=i;
sz[i]=1;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
}
sort(e+1,e+m+1,cmp_z);
for(int i=1;i<=p;i++)
{
scanf("%d",&q[i].k);
q[i].id=i;
}
sort(q+1,q+p+1,cmp_k);
LL ans=0;
int h=1;
for(int i=1;i<=p;i++)
{
int k=q[i].k;
while(e[h].z>=k&&h<=m)
{
int x=e[h].x,y=e[h].y;
int fx=f(x),fy=f(y);
if(fx==fy)
{
h++;
continue;
}
// ans=ans-1ll*sz[fx]*(sz[fx]-1)/2;
// ans=ans-1ll*sz[fy]*(sz[fy]-1)/2;
// ans=ans+1ll*(sz[fx]+sz[fy])*(sz[fx]+sz[fy]-1)/2;
ans=ans+1ll*sz[fx]*sz[fy];
fa[fx]=fy;
sz[fy]+=sz[fx];
h++;
}
q[i].ans=ans;
}
sort(q+1,q+p+1,cmp_id);
for(int i=1;i<=p;i++)
{
cout<<q[i].ans<<endl;
}
}
return 0;
}