题意:n个人,m对朋友,每寻找一个人传播消息需要花费相应的价钱,但是朋友之间传播消息不需要花费价钱,问最小的花费?
分析:不需要排序,只需要并查集求解即可。将朋友之间用并查集连接起来,然后对于每个集合,寻找最小的花费并加到sum中;对于没有朋友的人,直接把花费加到sum中。
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<string>
#include<stdlib.h>
using namespace std;
typedef long long ll;
const int maxn=1e6;
int n,m;
ll money[maxn];
int pre[maxn];
int find(int x){
if(x==pre[x])
return x;
return pre[x]=find(pre[x]);
}
void join(int x,int y){
int fx=find(x);
int fy=find(y);
if(fx==fy)
return;
pre[fy]=fx;
}
int main()
{
ll sum=0;
cin>>n>>m;
for(int i=0;i<=n;i++)
pre[i]=i;
for(int i=1;i<=n;i++)
cin>>money[i];//i为编号,money为价钱
int x,y;
for(int i=1;i<=m;i++){
cin>>x>>y;
join(x,y);
}
for(int i=1;i<=n;i++)//寻找最小值
money[find(i)]=min(money[find(i)],money[i]);
for(int i=1;i<=n;i++){
if(find(i)==i)//如果祖先是自己,就把钱加上去
sum+=money[i];
else
sum+=0;
}
cout<<sum<<endl;
return 0;
}