用的kruskal算法,用到了并查集,算法思路和代码实现过程都很好理解,标准的模板题
#include<bits/stdc++.h>
using namespace std;
const int N=5005;
const int M=200005;
int n,m;//n个节点,m条无向边
long long int lens=0;//最小生成树的各边的长度之和
int cnt=0;//连接上的边数
int parent[N];//父节点
struct Edge
{
int x,y,z;//两顶点和一边
}edge[M];
void initial()//初始化
{
for(int i=0;i<n;i++)
{
parent[i]=-1;
}
}
int find_root(int x)//寻找根结点
{
int x_root=x;
while(parent[x_root]!=-1)
{
x_root=parent[x_root];
}
return x_root;
}
inline bool cmp(Edge a,Edge b)
{
return a.z<b.z;
}
inline void kruskal()
{
sort(edge,edge+m,cmp);//将边按权值排序
for(register int i=0;i<m;i++)//重新接上m条边
{
//用到了并查集
int x_root=find_root(edge[i].x);
int y_root=find_root(edge[i].y);
if(x_root==y_root)
{
continue;//两个点已经连通,不再需要这条边
}
lens+=edge[i].z;//未连通则将此边权值加入总长
parent[y_root]=x_root,cnt++;//连接两节点,边数+1
if(cnt==n-1)
{
break;//接上的边数为n-1时,最小生成树创立完毕,循环结束
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>edge[i].x>>edge[i].y>>edge[i].z;
}//输入
initial();
kruskal();
//输出
if(cnt==n-1) cout<<lens;
else cout<<"orz";
return 0;
}