Educational Codeforces Round 33 (Rated for Div. 2) C题·(并查集变式)

C. Rumor

Vova promised himself that he would never play computer games... But recently Firestorm — a well-known game developing company — published their newest game, World of Farcraft, and it became really popular. Of course, Vova started playing it.

Now he tries to solve a quest. The task is to come to a settlement named Overcity and spread a rumor in it.

Vova knows that there are n characters in Overcity. Some characters are friends to each other, and they share information they got. Also Vova knows that he can bribe each character so he or she starts spreading the rumor; i-th character wants ci gold in exchange for spreading the rumor. When a character hears the rumor, he tells it to all his friends, and they start spreading the rumor to their friends (for free), and so on.

The quest is finished when all n characters know the rumor. What is the minimum amount of gold Vova needs to spend in order to finish the quest?

Take a look at the notes if you think you haven‘t understood the problem completely.

Input
The first line contains two integer numbers n and m (1 ≤ n ≤ 105, 0 ≤ m ≤ 105) — the number of characters in Overcity and the number of pairs of friends.

The second line contains n integer numbers ci (0 ≤ ci ≤ 109) — the amount of gold i-th character asks to start spreading the rumor.

Then m lines follow, each containing a pair of numbers (xi, yi) which represent that characters xi and yi are friends (1 ≤ xi, yi ≤ n, xi ≠ yi). It is guaranteed that each pair is listed at most once.

Output
Print one number — the minimum amount of gold Vova has to spend in order to finish the quest.

Input

5 2
2 5 3 4 8
1 4
4 5

Output

10

思路:明显的并查集。

AC代码:

#include<bits/stdc++.h>

using namespace std;
#define N 100009
#define int long long
int cost[N];
int f[N];
int getf(int v){
    if(v==f[v]){
        return f[v];
    }else{
        f[v]=getf(f[v]);
        return f[v];
    }
}
void merge(int u,int v){
    int t1=getf(u);
    int t2=getf(v);
    if(t1!=t2){
        f[t2]=t1;
    }
}
signed main(){
    int n,m;
    cin>>n>>m;
    int sb=0;
    int ans=0;
    for(int i=1;i<=n;i++){
        scanf("%lld",&cost[i]);
        sb+=cost[i];
        f[i]=i;
    }
    if(m==0){
        cout<<sb<<endl;
        return 0;
    }
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%lld%lld",&x,&y);
        merge(x,y);
    }
    /*for(int i=1;i<=n;i++){
        if(i==f[i]){
            cout<<i<<" ";
        }
    }
    cout<<endl;*/
    for(int i=1;i<=n;i++){
        cost[getf(i)]=min(cost[getf(i)],cost[i]);// 关键:将该每一个集合中的最小花费赋值给祖先。
    }//
    for(int i=1;i<=n;i++){
        if(i==f[i]){
            ans+=cost[i];
        }
    }
    printf("%lld\n",ans);
    return 0;
} 

原文地址:https://www.cnblogs.com/pengge666/p/11511099.html

时间: 2024-10-11 08:00:04

Educational Codeforces Round 33 (Rated for Div. 2) C题·(并查集变式)的相关文章

Educational Codeforces Round 33 (Rated for Div. 2) A题

A. Chess For Three Alex, Bob and Carl will soon participate in a team chess tournament. Since they are all in the same team, they have decided to practise really hard before the tournament. But it's a bit difficult for them because chess is a game fo

Educational Codeforces Round 33 (Rated for Div. 2) B题

B. Beautiful Divisors Recently Luba learned about a special kind of numbers that she calls beautiful numbers. The number is called beautiful iff its binary representation consists of k + 1 consecutive ones, and then k consecutive zeroes. Some example

Educational Codeforces Round 74 (Rated for Div. 2)补题

慢慢来. 题目册 题目 A B C D E F G 状态 √ √ √ √ × ? ? //√,×,? 想法 A. Prime Subtraction res tp A 题意:给定\(x,y(x>y)\),问能否将\(x-y\)拆成任意多个质数之和 1.任意大于\(1\)的整数\(k\)都可以用\(2\)与\(3\)的线性表示 证: 若\(k\)是偶数,显然: 若\(k\)是奇数,则\(k\)可以表示成\(k = 3 + 2*k'\),显然: 毕. #include<bits/stdc++.h&

Educational Codeforces Round 34 (Rated for Div. 2) B题【打怪模拟】

B. The Modcrab Vova is again playing some computer game, now an RPG. In the game Vova's character received a quest: to slay the fearsome monster called Modcrab. After two hours of playing the game Vova has tracked the monster and analyzed its tactics

codeforces Educational Codeforces Round 55 (Rated for Div. 2) C题 C. Multi-Subject Competition

这道题比赛时候没做出来,下来一看才发现是排序傻逼题. 把每个偏好的人做成一个vector,从大到小排序,做一个前缀和.然后将每种人数做一个桶,在桶里装每种科目选择人数为i的时候分数总和. 遍历每一维vector,把各个位置上面的vector加到sum数组中,最后sum数组里面挑出最大值. #include<bits/stdc++.h> using namespace std; typedef long long ll; vector<int> vec[100010];//vecto

Educational Codeforces Round 63 (Rated for Div. 2) B题

题目网址:https://codeforc.es/contest/1155/problem/B 题目大意:有两个人A,B博弈,在一串数字中,A先取数,B后取数,最后剩11个数的时候停止,如果第一个数是8,则A胜,反之B胜 题解:取数到最后,只剩11个数,且,A如果要赢,第一个数是8,则A显然是要尽可能的先取前面的非8数,B要先去前面的8,按照这样的策略,只需考虑前面n -10个数取到最后是否有8即可,显然是判断8的数量和其他数的数量的大小即可. 1 #include<bits/stdc++.h>

Educational Codeforces Round 63 (Rated for Div. 2) D题

题目网址:https://codeforc.es/contest/1155/problem/D 题目大意:给定n个数和一个k,可以对这n个数进行一次操作,也可以不进行,即选择某个区间中的数都乘上k,问最后最大连续子段和是多少? 题解:(鶸鶸的我是看别人的博客才解决的 ! ) 首先这道题的状态很多,对于前m个数,乘k之前的状态,乘k的状态,之和的状态都需要建立.那么分别设dp1,dp2,dp3是乘k之前,乘k时,乘k之和,前m个数最大连续子段和. 首先对于dp1,即一组数的最大子段和,显然只要是正

Educational Codeforces Round 78 (Rated for Div. 2) --补题

链接 直接用数组记录每个字母的个数即可 #include<bits/stdc++.h> using namespace std; int a[26] = {0}; int b[26] = {0}; int judge() { //cout<<"111"<<endl; for (int i = 0; i < 26; ++i) { if (a[i]!=b[i]) { return 0; } } return 1; } int main() { //

Educational Codeforces Round 57 (Rated for Div. 2)

get人生第二场CF! 成绩:(exACM) rank858 AC3/7 Penalty57 rating1648(+52) 题目:Educational Codeforces Round 57 (Rated for Div. 2) 错题题解: D. Easy Problem E. The Top Scorer F. Inversion Expectation G. Lucky Tickets 原文地址:https://www.cnblogs.com/xht37/p/10198321.html