HDU - 3938 Portal 离线并查集

https://vjudge.net/problem/HDU-3938

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=5e4+10;
int n,m,q;
int p[N],num[N];
struct node1{
	int u,v,w;
	bool operator< (const node1 W)const
	{
		return w<W.w;
	}
}g[N];
struct node2{
	int id,l;
	bool operator< (const node2 U)const
	{
		return l<U.l;
	}
}e[N];
int find(int x)
{
	if(p[x]!=x) p[x]=find(p[x]);
	return p[x];
}
int merge(int i,int j)
{
	int a=find(i),b=find(j);
	if(a==b) return 0; //在集合中,已经算过了 
	p[a]=b;
	
	int ans=num[a]*num[b];
	num[b]+=num[a];  //点的累加 在此之前二者没有关系,现在要将a过度给b  那么b应该加上a的点数  类似于问并查集 中有几个集合,每个集合有几个点 
	num[a]=0;
	return ans;
}
int main()
{
	int ans[N];
	while(~scanf("%d %d %d",&n,&m,&q))
	{
		memset(ans,0,sizeof ans);
		for(int i=0;i<m;i++)
			scanf("%d %d %d",&g[i].u,&g[i].v,&g[i].w);
		for(int i=0;i<q;i++)
		{
			scanf("%d",&e[i].l);
			e[i].id=i;
		}
		
		sort(g,g+m);
		sort(e,e+q);
		for(int i=1;i<=n;i++)
			num[i]=1,p[i]=i;
			
		int pos=0,tmp=0;
		for(int i=0;i<q;i++)
		{
			while(pos<m && e[i].l>=g[pos].w)
			{
				tmp+=merge(g[pos].u,g[pos].v);
				pos++;
			}
			ans[e[i].id]=tmp;
		}
		for(int i=0;i<q;i++)
			printf("%d\n",ans[i]);
	}
	return 0;
}
posted @ 2021-07-27 11:41  斯文~  阅读(26)  评论(0)    收藏  举报

你好!