(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.