关于时间复杂度:
prim:该算法的时间复杂度为O(n2)。与图中边数无关,该算法适合于稠密图。
kruskal:需要对图的边进行访问,所以克鲁斯卡尔算法的时间复杂度只和边又关系,可以证明其时间复杂度为O(eloge)。适合稀疏图。
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出 orz
。
输入格式
第一行包含两个整数 N,MN,M,表示该图共有 NN 个结点和 MM 条无向边。
接下来 MM 行每行包含三个整数 X_i,Y_i,Z_iXi,Yi,Zi,表示有一条长度为 Z_iZi 的无向边连接结点 X_i,Y_iXi,Yi。
输出格式
如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出 orz
。
输入输出样例
输入 #1复制
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出 #1复制
7
#include<bits/stdc++.h>
using namespace std;
int f[5005];
int sum=0;
struct node{
int a,b,len;
}mp[200005];
bool cmp(node a,node b){
return a.len<b.len;
}
int find(int x){
if(x==f[x]) return x;
f[x]=find(f[x]);
return f[x];
}
void myunion(int x,int y,int k){
int fx=find(x);
int fy=find(y);
if(fx!=fy){
sum+=mp[k].len;
f[fy]=fx;
}
}
int main(){
int n,m,a,b,k;
cin>>n>>m;
for(int i=0;i<m;i++){
cin>>a>>b>>k;
mp[i].a=a;
mp[i].b=b;
mp[i].len=k;
}
sort(mp,mp+m,cmp);
for(int i=0;i<=n;i++) f[i]=i;
for(int i=0;i<m;i++){
myunion(mp[i].a,mp[i].b,i);
}
cout << sum <<endl;
return 0;
}