牛客寒假训练第三场-G

并查集

题目链接

就是并查集的扩展。

用size数组记录每个连通块的大小,用maxn数组记录每个联通块中数的最大值,答案就是:每个连通块大小*该连通块中数的最大值

ac代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1000010;
int a[N];
int fa[N]; //  
int size[N]; // 每个连通块的大小 
int maxn[N]; //  每个连通块的最大值 
int n,m;
long long ans = 0;

int find(int x)
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void unionn(int x, int y)
{
	int fx = find(x);
	int fy = find(y);
	if(fx != fy){
		if(maxn[fx] < maxn[fy]){
			maxn[fx] = maxn[fy];
		}
		
		size[fx] += size[fy];
		fa[fy] = fx;
	}
}
int main()
{
	scanf("%d %d",&n, &m);
	for(int i=0; i<n; ++i) scanf("%d", &a[i]);
	
	for(int i=0; i<n; ++i){
		fa[i] = i;
		size[i] = 1;
		maxn[i] = a[i];
	}
	for(int i=0; i<m; ++i){
		int x, y;
		scanf("%d %d", &x, &y);
		unionn(x-1, y-1);	// 注意x,y的范围! 
	}
	
	for(int i=0; i<n; ++i){
		if(fa[i]==i) ans += size[i]*maxn[i];
	}

	printf("%lld", ans);
	return 0;
	
 } 
posted @ 2021-02-25 20:05  VanHope  阅读(33)  评论(0编辑  收藏  举报