牛客寒假训练第三场-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;
}