1、最小生成数的算法有prim算法和krukal算法。
2、这次说Krukal算法实现最小生成树
提醒:本代码第一个元素的下表从1开始,而不是从0开始,注意就好。
最后有 测试数据
//最小生成树——Krukal算法
#include<iostream>
#include<algorithm>
#include<malloc.h>
#define Max 10001 //模拟无穷大
#define MaxSize 10 //最多点数
using namespace std;
typedef struct{
int left;
int right;
int weight;
}edgeArray;
//1)图的数据类型
typedef struct
{
int vertex[MaxSize];//存储点的信息
int belong[MaxSize];//属于分支号
int edge[MaxSize][MaxSize];//边的信息
int vertexNum;//点的个数
int edgeNum;// 边的个数
}MGraph;
//2)构造一个图
MGraph CreatGraph(int n,int m,edgeArray ea[]){
MGraph G;
int a,b,c;
//点 边
G.vertexNum=n;
G.edgeNum=m;
//点的信息
for(int i=1;i<=G.vertexNum;i++){
G.vertex[i]=i;
G.belong[i]=i; //一开始,要把每个点看成独立的,即属于的分支是他自己
}
//边邻接关系的初始化
for(int i=1;i<=G.vertexNum;i++){
for(int j=1;j<=G.vertexNum;j++){
if(i==j){
G.edge[i][j]=0;
}else{
G.edge[i][j]=Max;
}
}
}
//输入m行边的信息
printf("请输入 点号 点号 边值:\n");
for(int i=1;i<=G.edgeNum;i++){
scanf("%d %d %d",&a,&b,&c);
G.edge[a][b]=c;
G.edge[b][a]=c;//无向图
ea[i].left=a;
ea[i].right=b;
ea[i].weight=c;
}
return G;
}
//3)对EDGE升序排序 sort函数的排序方式函数,<algorithm>+sort(array,cmp)
bool cmp(edgeArray e1,edgeArray e2){
return e1.weight<e2.weight;
}
//4)核心算法
MGraph Krukal(MGraph G,int n,int m,edgeArray ea[]){
//边邻接关系的 复初始化
for(int i=1;i<=G.vertexNum;i++){
for(int j=1;j<=G.vertexNum;j++){
if(i==j){
G.edge[i][j]=0;
}else{
G.edge[i][j]=Max;
}
}
}
//连接新边
edgeArray e;
int isTongYi=0; //是否所有点的分支号统一?
int edgeNumTrue = 0;
for(int i=1;i<=m;i++){
e = ea[i];
if(G.belong[e.left]!=G.belong[e.right]){//一边的两点属于不同分支
int l = G.belong[e.left];
int r = G.belong[e.right];
for(int j=1;j<=n;j++){//默认把右分支全部统一成左分支
if(G.belong[j]==r){
G.belong[j] = l;
}
}
}
//全局是否同一图
isTongYi = 1;
for(int j=2;j<=n;j++){
if(G.belong[j]!=G.belong[j-1]){
isTongYi =0;
break;
}
}
if(isTongYi == 1){
edgeNumTrue = i;
break;
}
}
G.edgeNum = edgeNumTrue;
for(int i = 1;i<=G.edgeNum;i++){
G.edge[ea[i].left][ea[i].right] = ea[i].weight;
G.edge[ea[i].right][ea[i].left] = ea[i].weight;
}
return G;
}
void display(MGraph G){
for(int i =1;i <= G.vertexNum;i++){
for(int j =1;j <= G.vertexNum;j++){
if(G.edge[i][j]==Max) cout<<"max ";
else cout<<G.edge[i][j]<<" ";
}
cout<<endl;
}
}
int main(){
int n;
int m;
printf("请输入点数和边数:\n");
scanf("%d %d",&n,&m);
edgeArray ea[MaxSize*MaxSize];
MGraph G;
G = CreatGraph(n,m,ea);
cout<<endl<<"原始图";
display(G);
sort(ea+1,ea+m+1,cmp);
G = Krukal(G,n,m,ea);
cout<<endl<<"最小生成树图";
display(G);
return 0;
}
3、测试数据 根据这个图,找最小生成树
4、改进
完全可以不初始化之前的图,一边输入 (点号 点号 边值),一边记录到edgeArray里面,然后排序,然后进行Krukal算法。你可以试试。