#并查集# [ssloj 1486] 旅游 [jzoj travel]

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; 	
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值