kruskal的时间复杂度是O(eloge)。这里因为要给边排序,所以要用结构体存图。
然后用到了并查集检查两个点是否在同一连通分量里,以为在同一连通分量里的两个点如果链接一定形成了环,就不是树了。
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
struct EDGE{
int u;
int v;
int w;
};
int n,m;
EDGE edge[1000];
bool vis[2000];
int father[1000],son[1000];
int sum, edgenum;
int unionnode(int x){
return x == father[x] ? x : unionnode(father[x]);
}
bool join(int u, int v){
int root1, root2;
root1 = unionnode(u);
root2 = unionnode(v);
if(root1 == root2){
return false;
}
else father[root1] = father[root2];
return true;
}
bool cmp(EDGE a,EDGE b){
if(a.w < b.w)
return true;
else
return false;
}
int main() {
sum = 0;
edgenum = 0;
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
edge[i].u = u;
edge[i].v = v;
edge[i].w = w;
}
for(int i = 1; i <= n; ++i)
{
father[i] = i;
}
sort(edge, edge+m,cmp);
bool flag = false;
for(int i = 0; i < m; i++){
if(join(edge[i].u, edge[i].v)){
edgenum++;
sum += edge[i].w;
cout << edge[i].u << "--->" << edge[i].v << endl;
}
if(edgenum == n - 1 ){
flag = true;
break;
}
}
if(flag) {
cout << sum << endl;
}else cout <<"ERROR!\n" << endl;
return 0;
}