正题
题目大意
nnn个点mmm条边,qqq次询问走边权小于xxx的能联通的点对数。
解题思路
将边权排序,然后并查集预处理答案即可。
时间复杂度O(mlogm)O(m\log m)O(mlogm)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+10;
struct node{ll x,y,w;
}e[N];
ll T,n,m,q,fa[N],siz[N],ans[N];
bool cmp(node x,node y)
{return x.w<y.w;}
ll find(ll x)
{return (fa[x]==x)?(x):(fa[x]=find(fa[x]));}
int main()
{scanf("%lld",&T);while(T--){memset(ans,0,sizeof(ans));scanf("%lld%lld%lld",&n,&m,&q);for(ll i=1;i<=n;i++)fa[i]=i,siz[i]=1;for(ll i=1;i<=m;i++)scanf("%lld%lld%lld",&e[i].x,&e[i].y,&e[i].w); sort(e+1,e+1+m,cmp);for(ll i=1;i<=m;i++){ll x=find(e[i].x),y=find(e[i].y);if(x==y)continue;ans[e[i].w]+=siz[x]*siz[y]*2;fa[y]=x;siz[x]+=siz[y];}for(ll i=1;i<=1e5;i++)ans[i]+=ans[i-1]; for(ll i=1;i<=q;i++){ll x;scanf("%lld",&x);printf("%lld\n",ans[x]);}}
}