codeforces893C

题意: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;
}

猜你喜欢

转载自blog.csdn.net/zsnowwolfy/article/details/84843418