#include<bits/stdc++.h>
using namespace std;
//kruskal算法
int F[1000];
int N,M;
int Find(int x)//找到x的父节点
{
if (x == F[x]) return x;//直接找到就返回 就一个等于号的问题
else {//没找到 就递归的找 而且找的时候 还要不断的赋值 这样下次就方便了
int f = Find(F[x]);
F[x] = f;
return f;
}
}
void Union (int a,int b)
{
int fa = Find(a);
int fb = Find(b);
if (fa==fb) return;
F[fa] = fb;
}
typedef struct edge{
int u,v;
int cost;
}edge;
edge E[1006];
bool cmp (edge a,edge b)
{
return a.cost < b.cost;
}
int ans,num;
int kruskal()
{
for (int i = 0;i<M;i++)
{
int fu = E[i].u;
int fv = E[i].v;
if (Find(fu) != Find(fv))
{
// cout << Find(fu) << "+++" << Find(fv) << endl;
// cout << fu <<"**" << fv <<"**" << E[i].cost << endl;
Union(fu,fv);
// cout << Find(fu) << "+++" << Find(fv) << endl;
ans+=E[i].cost;
num++;
if (num==N-1) break;
}
}
if (num!=N-1) return -1;
return ans;
}
int main()
{
cin >> N >> M;
for (int i = 0;i<M;i++)
{
int a,b,c;
cin >> a >> b >> c;
E[i].u = a;
E[i].v = b;
E[i].cost = c;
}
sort(E,E+M,cmp);
// for (int i = 0;i<=M;i++) cout << E[i].cost << endl;
for (int i = 0;i<=N;i++) F[i] = i;//初始化并查集
// kruskal();
cout << kruskal();
return 0;
}
感觉这个思路是最好理解的,而且实现在c++里面也不难,就是设置结构体,然后依据边的权值从小到大排序,每次都判断一下那个边是否在一个集合内,如果不在就需要union起来,对于n个点而言,只需要n-1个边,所以可以提前判断一下,提前退出。
至于c语言的话,那个结构体的大小排序换一下,其他的基本上类似。