2.按照老师课件上思想编写
3.加入了二维数组T[MAX][2],用来存放最小生成树的最终选择最小权值的节点信息
利用for循环可查看:
for(i=1;i<n;i++){//输出存放在数组中的最小生成树边集
printf("%d %d\n",T[i][1],T[i][2]);
}
4.arcs[MAX][MAX];
5.没有将终点信息赋值给一个数组
lowcost[MAX];终点 lowcost[i]记录以i为终点的边的最小权值,当lowcost[i]=0时表示终点i加入生成树;
因为它是可要可不要的,要的话程序看起来会比剑清楚,建议要
因老师给的课件上没有,所以此程序中没有用到,
对比用处:lowcost[j]<min
arcs[j][nearly[j]]<min
6.nearly[MAX];
类似与mst[MAX]起点 mst[i]记录对应lowcost[i]的起点,当mst[i]=0时表示起点i加入生成树
但是与mst[MAX]还是不同,因为他不必要代表起点,(理解为起点也可)仅仅用1/0表示在不在集合中就可以了
7.默认选择1号节点加入生成树,从2号节点开始初始化
8.将下面数据保存到1.txt
6 10
1 2 10
1 4 30
1 5 45
2 3 50
2 5 50
2 6 25
3 5 35
3 6 15
4 6 20
5 6 55
#include <stdio.h>
#define INFINITY 0x7fffffff
#define MAX 100//最大顶点数
int arcs[MAX][MAX];
int Prim(int arcs[][MAX],int n){
int i,j,k;
int mincost=0;
int T[MAX][2];
int nearly[MAX];//nearly(j)是生成树中离j(不在生成树中)最近的点
for(i=2;i<=n;i++){//初始化
nearly[i]=1;//默认从节点1开始
}
nearly[1]=0;
for(i=1;i<n;i++){//找最小生成树的边
int min=INFINITY;
int minid=0;
for(j=2;j<=n;j++){
if(arcs[j][nearly[j]]<min&&nearly[j]!=0){//j是终节点,nearly[j]是初始节点,找不在生成树中的节点j,使离nearly[j](树中节点)最近
min=arcs[j][nearly[j]];//最近的边的权值
minid=j;//哪个j离树中节点nearly[j]最近
}
}
//printf("%d\n",min);
//printf("%d\n",minid);
T[i][1]=minid;
//printf("%d\n",nearly[minid]);
T[i][2]=nearly[minid];//将这最小权值边上的两个点存入数组中
mincost+=min;
printf("%d %d %d",T[i][1],T[i][2],min);
printf("\n");
nearly[minid]=0;//一旦找到下一个权值最小的节点另nearly=0,使其加入树中
for(k=2;k<=n;k++){//修改其余不在树中的节点到树中节点的最小权值,这是由于加入了新的节点而使原来到树中节点的距离改变,可能到新的节点的距离是最小的了
if(arcs[k][nearly[k]]>arcs[k][minid]){//如果不在树中的节点k到开始在树中节点nearly[k]的权值,大于加入新节点minid后,k到minid的权值,
nearly[k]=minid;//则修改与k节点有最小权值的树中节点nearly[k]的值
}
}
}
for(i=1;i<n;i++){//输出存放在数组中的最小生成树边集
printf("%d %d\n",T[i][1],T[i][2]);
}
return mincost;
}
int main()
{
int i, j, m, n,p,q;
int minCOST;
FILE *fp;
fp=fopen("1.txt", "r");
printf("图的节点数为:");
fscanf(fp, "%d", &p);
printf("%d", p);
printf("图的边数为:");
fscanf(fp, "%d", &q);
printf("%d", q);
printf("\n");
for (i = 1; i <= p; i++)//节点数,构造二维数组
{
for (j = 1; j <= p; j++)
{
arcs[i][j] = INFINITY;
}
}
//printf("输入读取的边数");
//scanf("%d",&n);
/* 读取边信息 */
for (i = 1; i <= q; i++)//边数
{
fscanf(fp,"%d", &m);
fscanf(fp,"%d", &n);
fscanf(fp,"%d", &arcs[m][n]);
arcs[n][m]=arcs[m][n];
printf("%d %d %d\n", m,n,arcs[m][n]);
}
printf("\n");
minCOST=Prim(arcs,p);
printf("最小生成树的权值和为:%d",minCOST);
return 0;
}