2.其余与yyprim类似;
3.将下面数据保存到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//最大顶点数
typedef int KeyType;
typedef char InfoType[10];
int arcs[MAX][MAX];
typedef struct{
KeyType key,k1,k2;//关键字项
InfoType data;//其他数据类型
}RecType;
void Sift(RecType R[],int s,int m){//调整堆,m为节点个数,s为父节点
int j;
RecType temp=R[s];
for(j=2*s;j<=m;j=2*j){
if(j<m&&R[j].key<R[j+1].key)j++;//若右孩子较大则把j指向右孩子
if(temp.key>R[j].key){//"<"得到结果为小根堆,首先输出的是最大的边,“>”得到的是大根堆,首先找到最小的边
R[s]=R[j];//将R[j]调整到双亲节点位置
s=j;//j的值赋给s,然后找树的下一个分支根节点
}
else break;
}
R[s]=temp;
}
int Prim(int arcs[][MAX],int n,int s,int m,int p){
//printf("最小边是:%d\n",s);
//printf("节点是:%d %d\n",m,p);
int i,j;
int sum=s;
int lowcost[MAX];//lowcost[i]记录以i为终点的边的最小权值,lowcost[i]=0,表示终点i加入生成树
int mst[MAX];//near[i]记录对应lowcost[i]的起点,near[i]=0表示i加入生成树
/*初始化节点,默认已选择1号节点加入生成树,从2号节点开始初始化*/
for(i=1;i<=n;i++){
if(arcs[i][m]<arcs[i][p]){
lowcost[i]=arcs[i][m];
mst[i]=m;//标记起点m
}
else{
lowcost[i]=arcs[i][p];
mst[i]=p;//标记起点p
}
}
mst[m]=0;//标记m号节点已经加入生成树
mst[p]=0;//标记n号节点已经加入生成树
/*找其余n-2条边*/
for(i=2;i<n;i++){
int min=INFINITY;
int minid=0;
/*找满足条件的最小权值的边以及节点*/
for(j=1;j<=n;j++){
if(lowcost[j]<min&&mst[j]!=0){
min=lowcost[j];//哪条边权值最小,赋给min
minid=j;//该权值最小的边的终点j赋给minid
}
}
/* 输出生成树边的信息:起点,终点,权值 */
printf("%d %d %d",mst[minid],minid,min);
printf("\n");
lowcost[minid]=0;//标记节点minid加入生成树
sum+=min;
/*更新当前节点minid到其他节点的权值*/
for(j=1;j<=n;j++){
if(arcs[minid][j]<lowcost[j]){//
lowcost[j]=arcs[minid][j];//更新权值信息
mst[j]=minid;//更新最小权值边的起点
}
}
}
return sum;
}
int main()
{
int i, j,k, m, n,p,q;
int minCOST;
RecType R[MAX];
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];
R[i].key=arcs[m][n];
R[i].k1=m;
R[i].k2=n;
printf("%d %d %d\n", m,n,arcs[m][n]);
//printf("%d\n",arcs[n][m]);
}
printf("\n");
printf("初始关键字");
for(k=1;k<=q;k++){
printf("%3d",R[k].key);
}
printf("\n");
/*循环建立初始堆*/
for(i=n/2;i>=1;i--)Sift(R,i,n);//循环建立初始堆,将其建为大根堆
printf("最小边是:%d\n",R[1].key);
printf("节点是:%d %d\n",R[1].k1,R[1].k2);
//printf("%d\n",arcs[1][2]);
minCOST=Prim(arcs,p,R[1].key,R[1].k1,R[1].k2);
printf("最小生成树的权值和为:%d",minCOST);
return 0;
}