小沙的魔法 题解(思维+并查集)

题目链接

题目思路

假设没有连边,那么答案就是\(\sum a[i]\)

每次连一条边如果如果\(u,v\)本身不在一个连通块,就能减去\(min(a[u],a[v])\) 那么直接排序即可

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define ll long long
const int maxn=5e6+5;
int n,m;
int a[maxn];
int fa[maxn];
ll ans;
int findd(int x){
    return x==fa[x]?fa[x]:fa[x]=findd(fa[x]);
}
struct node{
    int u,v,w;
}e[maxn];
bool cmp(node a,node b){
    return a.w>b.w;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        fa[i]=i;
        scanf("%d",&a[i]);
        ans+=a[i];
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d",&e[i].u,&e[i].v);
        e[i].w=min(a[e[i].u],a[e[i].v]);
    }
    sort(e+1,e+1+m,cmp);
    int cnt=min(5*n,m);
    for(int i=1;i<=m;i++){
        if(cnt==0) break;
        int u=findd(e[i].u);
        int v=findd(e[i].v);
        if(u==v) continue;
        ans-=e[i].w;
        cnt--;
        fa[u]=v;
    }
    printf("%lld\n",ans);
    return 0;
}

posted @ 2022-01-27 14:44  hunxuewangzi  阅读(31)  评论(0编辑  收藏  举报