(1)将所有边按权重从小到大排序。O(mlogm)

(2)枚举每条边(a,b,c)边a-b权重为c

 如果当前a,b不连通,将这条边加入到最小生成树集合中。(连通块点 的数量)O(m)

【并查集】连通块中的点的数量_暮色_年华的博客

import java.io.*;
import java.util.*;
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static Scanner sc = new Scanner(System.in);
    static int n;
    static int m;
    static int p[];
    static int find(int x){
        if(p[x]!=x)p[x]=find(p[x]);
        return p[x];
    }
    public static void main(String[] args) {
         n=sc.nextInt();
         m=sc.nextInt();
         p=new int[n+1];
         for(int i=1;i<=n;i++)p[i]=i;

         Edge[]edges=new Edge[m];
         for(int i=0;i<m;i++){
             int a=sc.nextInt();
             int b=sc.nextInt();
             int w=sc.nextInt();
             edges[i]=new Edge(a,b,w);
         }
         Arrays.sort(edges,(e1,e2)->{
            return e1.w- e2.w;
         });
         int res=0;
         int cnt=0;
         for(int i=0;i<m;i++){
             int a=edges[i].a;
             int b=edges[i].b;
             int w=edges[i].w;
             a=find(a);
             b=find(b);
             if(a!=b) {
                 p[a] = b;
                 res += w;
                 cnt++;
             }
         }
         if(cnt<n-1) System.out.println("impossible");
         else System.out.println(res);

    }
}
class Edge{
    int a;
    int b;
    int w;
    Edge(int a,int b,int w){
        this.a=a;
        this.b=b;
        this.w=w;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.

c++实现:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int n,m;
vector<vector<int>>edges;
bool cmp(vector<int>a,vector<int>b){
    return a[2]<b[2];
}
vector<int>p;
int find(int x){
    if(p[x]!=x)p[x]=find(p[x]);
    return p[x];
}
int main(){
    cin>>n>>m;
    p.resize(n+1);
    for(int i=1;i<=n;i++)p[i]=i;
    int a,b,c;
    for(int i=0;i<m;i++){
        cin>>a>>b>>c;
        edges.push_back({a,b,c});
    }
    sort(edges.begin(),edges.begin()+m,cmp);
    int res=0;
    int cnt=0;
    for(int i=0;i<m;i++){
        a=find(edges[i][0]);
        b=find(edges[i][1]);
        if(a==b)continue;
        else {
            p[a]=b;
            cnt++;
            res+=edges[i][2];
        }
    }
    if(cnt<n-1)cout<<"impossible";
    else cout<<res;
    return 0;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.