/* 普利姆算法求解最小生成树,它有两个集合,已选点构成一个集合,未被选出的点都成那个一个集合
需要三个辅助的数组,adjvex[n]储存边的起点
lowcost[n]用来储存选出边的权值,vexs[n]用来储存终结点 ,他们需要 一一对应 ,起初所有节点的
间的权值都为无穷大,选出一个起始节点,把它的临结点的所有边的权值,按照顺序存入数组vexs,起始节点存放入adjex,
(根据邻接矩阵,如果它是第j行第 i列,就把边的权值存放在loecost[i]中,权值,起始点,和终点存入数组的下标一致),
然后选出和起始节点相连接的权值最小的临结点,输出对应的起点和终点,然后让这个边的权值变为无穷大,表示已经选出该边
然后这个点的所有边的权值记录到数组lowcost[n]中 ,把这个结点值存入到adjvex[n],然后重复此步骤,选出n-1条边。
*/
#include <stdio.h>
#include<iostream>
#include <string.h>
#define maxint 32726
#define maxvex 100
#define max 100
int sum=0;
using namespace std;
typedef struct{
char vexs[maxvex];
int arcs[maxvex][maxvex];
int vexnum,arcnum;
}Amg;
//邻接矩阵查找节点的位置
int locate(char vexs[] , char vex,int n){
int i,j;
for(i=1;i<=n;i++){
if(vexs[i]==vex){
j=i;
}
}
return j;
}
//用邻接矩阵建立图
void Creat1UND(Amg &G){
char v1,v2;//两个顶点的值
int w;//边的权值
int q,e;//顶点的坐标
printf("请输入顶点数和边数:");
cin>>G.vexnum>>G.arcnum;
printf("请输入各顶点的值:\n");
for(int i=1;i<=G.vexnum;i++){
cin>>G.vexs[i];
}
for(int i=1;i<=G.vexnum;i++){
for(int j=1;j<=G.vexnum;j++){
G.arcs[i][j]=maxint;
}
}
printf("请输入两个顶点以及权值;\n");
for(int k=1;k<=G.arcnum;++k){
cin>>v1>>v2>>w;
q=locate(G.vexs,v1,G.vexnum);
e=locate(G.vexs,v2,G.vexnum);
G.arcs[q][e]=w;
}
for(int i=1;i<=G.vexnum;i++){
for(int j=1;j<=G.vexnum;j++){
printf("%-10d ",G.arcs[i][j]) ;
}
printf("\n");
}
}
//普里姆算法求最小生成树
void Minitree(Amg &G,char u){
char adjvex[G.vexnum+1]={0};//记录起始点的数组
int lowcost[G.vexnum+1];//储存权值
for(int i=1;i<=G.vexnum;i++){//起初所有节点都没选出,权值都为无穷
lowcost[i]=maxint ;
}
int min=maxint;//用来比较的值
int m,b=locate(G.vexs,u,G.vexnum); //找出第一个结点的下标
lowcost[b]=maxint ;
for(int i=1;i<=G.vexnum;i++){//把它的所有临结点的权值存入lowcost中
if(G.arcs[b][i]<maxint){
adjvex[i]=G.vexs[b];//对应边的起始点
lowcost[i]=G.arcs[b][i];
}
}
for(int i=1;i<G.vexnum;i++){//n-1 次循环
for(int j=1;j<=G.vexnum;j++){
if(lowcost[j]<min){//找出最小边的权值
min=lowcost[j];
m=j;
}
}
sum+=min;//记录权值
printf("最小生成树为:");
printf("<%c %c> ",adjvex[m],G.vexs[m]);//输出这个边
lowcost[m]=maxint;//将选出边的权值改为无穷
min=maxint;//更新最小值
for(int k=1;k<=G.vexnum;k++){
if(G.arcs[m][k]<maxint){//将选出新的结点的所有临结点的权值进入数组中,并还有对应的起始点
adjvex[k]=G.vexs[m];
lowcost[k]=G.arcs[m][k];
}
}
}
printf("权值和为:%d",sum);
}
/*
输入结点数 6 边数 10
各个结点和权值
1 3 1
3 4 5
1 4 5
1 2 5
2 3 5
2 5 3
5 3 6
5 6 6
6 4 2
3 6 4
*/
int main(){
char b;
Amg G;
Creat1UND(G);
cin>>b;
Minitree(G, b);
return 0;
}
普里姆算法构造最小生成树
最新推荐文章于 2025-05-19 00:02:46 发布