欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【杭电多校2020】第二场1001.Total Eclipse(并查集)

程序员文章站 2022-08-15 19:17:19
题目链接思路:按照权值从大到小排序,然后依次加入,并把全场的权值都减到当前权值。用并查集维护连通块的总个数即可。代码:#includeusing namespace std;#define int long long#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);const int N=1e5+7;const int M=4e5+8;const double eps=1...

题目链接

思路:

按照权值从大到小排序,然后依次加入,并把全场的权值都减到当前权值。用并查集维护连通块的总个数即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N=1e5+7;
const int M=4e5+8;
const double eps=1e-8;
const int mod=1e9+7;
const int inf=0x7fffffff;
const double pi=3.1415926;
int a[N],h[N],e[M],ne[M],f[N],q[N],fa[N],idx;
bool visit[N];
void add(int a,int b)
{
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
int find(int x)
{
	if(x!=f[x])
	{
		f[x]=find(f[x]);
	}
	return f[x];
}
int cmp(int x,int y)
{
	return a[x]>a[y];
}
signed main()
{
	IOS;
	int t;
	cin>>t;
	while(t--)
	{
		memset(h,-1,sizeof h);
		memset(visit,0,sizeof visit);
		memset(fa,0,sizeof fa);
		int n,m;
		cin>>n>>m;
		idx=0;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			f[i]=q[i]=i;
		}
		for(int i=1;i<=m;i++)
		{
			int x,y;
			cin>>x>>y;
			add(x,y);
			add(y,x);
		}
		sort(q+1,q+1+n,cmp);
		for(int i=1;i<=n;i++)
		{
			int u=q[i];
			visit[u]=1;
			for(int j=h[u];~j;j=ne[j])
			{
				int k=e[j];
				if(!visit[k])
				{
				    continue;
				}
				int v=find(k);
				if(v==u)
				{
				    continue;
				}
				f[v]=fa[v]=u;
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			ans+=a[i]-a[fa[i]];
		}
		cout<<ans<<endl;
	}
	return 0;
}

本文地址:https://blog.csdn.net/ACkingdom/article/details/107570643

相关标签: 并查集