【cf893c Rumor】 并查集

题意是我们需要向所有人散播谣言,向第i个人散播谣言需要ci个金币,除此之外还有m个朋友关系,知道谣言的人会将谣言告诉他的朋友,求最小花费。
这题是很典型的并查集,我们只需要在合并时比较两个根节点的大小,将大的合并到根节点小的集合上去即可。

AC代码:

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
using namespace std;

typedef long long ll;

const int MAXN = 100005;

int s[MAXN],p[MAXN];
bool e[MAXN]; //在最后计算时记录这个点是否已经知道谣言
int n,m;

int myfind(int x){
	if(p[x]!= x) p[x]=myfind(p[x]);
	return p[x];
}

void myunion(int x,int y){
	x=myfind(x);
	y=myfind(y);
	if(s[x]>s[y]) p[x]=y; //将根节点大的合并到根节点小的集合上
	else p[y]=x;
}

int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&s[i]);
		p[i]=i;
		e[i]=0;
	}
	while(m--){
		int a,b;
		scanf("%d %d",&a,&b);
		myunion(a,b);
	}
	ll sum=0;
	for(int i=1;i<=n;i++){
		if(!e[myfind(i)]){
			sum+=s[p[i]];
			e[p[i]]=1;
		}
	}
	printf("%lld",sum);
	return 0;
}
posted @ 2020-11-06 14:15  樱与梅子  阅读(85)  评论(0)    收藏  举报