基本思想:
将所有顶点之间路径权值,从小到大有序排列,并在程序中优先遍历路径小的顶点,记录不存在环的路径,直至全部循环完毕。
关键:
1、将输入的边的顺序按边的权值从小到大排序。
2、在遍历的过程中判断是否生成环(难点)。
样例:
这里我用123456来代替ABCDEF
样例输入:
6 10
1 2 6
1 3 1
1 4 5
2 3 5
3 4 5
2 5 3
3 5 6
3 6 4
4 6 2
5 6 6
样例输出:
依次连接的边:
1 3 1
4 6 2
2 5 3
3 6 4
2 3 5
总权值:15
代码实现:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct edge
{
int s,e,w;
};
bool operator < (const edge &a,const edge &b)
{
return a.w<b.w;
}
int Find(int *p,int f)
{
while(p[f]>0)
f=p[f];
return f;
}
int main()
{
cout<<"输入顶点和边的个数:"<<endl;
int n,m;
cin>>n>>m;
cout<<"输入起点、终点和权值"<<endl;
edge a[1000];
int i,d,t;
for(i=0;i<m;i++)
{
cin>>a[i].s>>a[i].e>>a[i].w;
}
sort(a,a+m);
int b[1000]; //存放最小生成树的顶点
int sum=0;
memset(b,0,sizeof(b));
cout<<"依次连接的边:"<<endl;
for(i=0;i<m;i++)
{
d=Find(b,a[i].s);
t=Find(b,a[i].e);
if(d!=t) //d==t代表会形成环
{
sum+=a[i].w;
b[d]=t;
cout<<a[i].s<<" "<<a[i].e<<" "<<a[i].w<<endl;
}
}
cout<<"总权值:"<<sum<<endl;
return 0;
}
输出截图: