2021牛客寒假演算法基礎集訓營3 G.糖果(並查集)
阿新 • • 發佈:2021-02-07
技術標籤:2021牛客寒假演算法基礎集訓營
G.糖果
題目連結:https://ac.nowcoder.com/acm/contest/9983/G
題目描述:
在一個幼兒園裡面有n個小朋友,分別編號1,2,…,n。在這些小朋友中有一些小朋友互為朋友關係,總共有m對朋友。
作為幼兒園老師,你想買一些糖果分給小朋友,你知道第i個小朋友想要至少ai個糖果,否則他就會不開心。同時,如果一個小朋友得到的糖果數小於他某個朋友得到的糖果數,他也會不開心。
請問你最少買多少糖果才能保證每個小朋友都不會不開心呢?
輸入描述:
第一行以空格分隔的兩個整數n,m。
第二行以空格分隔的n個正整數ai。
接下來m行每行以空格分隔的兩個正整數u,v,代表u是v的朋友,v是u的朋友。
0≤m≤10^6
1≤ai≤10^9
1≤u,v≤n,u≠v
輸出描述:
購買的最少糖果數以保證每個小朋友都不會不開心。
示例1:
輸入
3 1
1 2 3
1 2
輸出
7
說明
給第三個小朋友買3個糖果,前兩個小朋友都買2兩個糖果,總共至少買7個糖果。注意如果給第一個小朋友只買了1個糖果,那麼他在看到自己的好朋友2有2個糖果的情況下,他就會不開心。
解題思路:
互為好朋友的人拿到的糖果數量一致,且為該小朋友所有好朋友糖果裡面的最大值(並查集的最大值)。要注意的是m對小朋友,小朋友的小朋友不一定是好朋友。
程式碼如下:
#include<iostream>
#include <algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
ll f[1000010],a[1000010];
int find(int x){
if(x==f[x])return x;
return f[x]=find(f[x]);
}
int main(){
ll n,m,x,y,ans=0;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
f[i]=i;
}
for(int i=1;i<=m; i++){
cin>>x>>y;
ll t1=find(x),t2=find(y);
f[t1]=t2; //合併互為朋友關係
a[t2]=max(a[t1],a[t2]); //更新最大值
}
for(int i=1;i<=n;i++)
ans+=a[find(i)];
cout<<ans<<endl;
return 0;
}