#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
#define MAXSIZE 10000
typedef int adjmatrix[MAX][MAX];///定义一个邻接矩阵
typedef struct node///边的结构体,也就是边的信息
{
int from,to;///树的起点和终点
int weight;///数的权值
}Edge;
int arcnum,n;///arcnum是边的数量,n是顶点的个数,我定义在全局变量就不需要去再传递参数了
void creat_matrix(adjmatrix G);///创建邻接矩阵
void prim(adjmatrix G,Edge *T);///利用prim算法从出发点求邻接矩阵表示的图的最小生成树
void print(Edge *T);///输出
int main()
{
adjmatrix G;///定义一个邻接矩阵
Edge T[MAX];///T就是最小生成树
printf("请输入有顶点数:");
scanf("%d",&n);///顶点数
creat_matrix(G);///创建邻接矩阵
prim(G,T);///prim算法
print(T);///输出路径和最小成本
return 0;
}
///创建邻接矩阵
void creat_matrix(adjmatrix G)
{
int i,j,k,e;
char x,y;
for(i=1;i<=n;i++)///初始化矩阵
{
for(j=1;j<=n;j++)
if(i==j)
G[i][j]=0;///对角线,也就是它本身初始化为0
else
G[i][j]=MAXSIZE;///如果不是,都是先初始化一个很大的值
}
printf("请输入边的个数:");
scanf("%d",&arcnum);
printf("起点 终点 权值:\n");
for(k=1;k<=arcnum;k++)///给每个边进行赋值
{
scanf(" %c %c %d",&x,&y,&e);///这里我定义是字符类型,%c是会读取回车键的,所以我在前面空格一下
i=x-'A'+1;///A相当于是位置1,赋值到矩阵就得相应转换成整型,不再是字符型
j=y-'A'+1;///类似
G[i][j]=e;///这是双向的,i->j的路径长度为e
G[j][i]=e;///这是双向的,j->i的路径长度为e
}
}
///利用prim算法从出发点求邻接矩阵表示的图的最小生成树
void prim(adjmatrix G,Edge *T)
{
int i,j,k,min,u,w,m;
Edge t;///暂时的
k=1;
for(i=1;i<=n;i++)///初始化T的结构体信息,首个顶点指向各个顶点
{
if(i!=1)///要那样的话就不能是i=1了 所以有了这个条件
{
T[k].from=1;///出发点都是1
T[k].to=i;///然后1出发到每个顶点
T[k].weight=G[1][i];///然后把1到各个顶点的权值赋值到T里面
k++;///然后自增
}
}
for(k=1;k<n;k++)///只要进行n-1次操作就行了
{
min=MAXSIZE;///先给min赋值一个很大的值,那么我接下来有进行比较最小,最小的值就会进行更新,这样比较方便
m=k;///m是这个是现在操作的这个顶点,用另外一个遍历是为了不改变k的值,影响到循环的遍历
for(j=k;j<n;j++)///从k之后以及k进行比较,找到这其中最小的
{
if(T[j].weight<min)///一直更新最小值,直到结束
min=T[j].weight,m=j;///m=j是最小值的位置,下面要进行再次的比较
}
t=T[k];///t就暂时的,T[k]就是最开始的信息,那么我找到了最小值的位置之后就要进行改变,把最小值的信息赋值到k的位置
T[k]=T[m];///就是变换
T[m]=t;
j=T[k].to;///新增加最小生成树T中的顶点序号赋给j
for(i=k+1;i<n;i++)///修改相关的边,就得让T中以及T外的每个顶点保持一条到现在最短的边
{
u=T[i].to;///u就是这个j所指向的顶点
w=G[j][u];///然后这个w就是代表j->u的权值,也就是接下来的每条边的权值
if(w<T[i].weight)///如果比之前所赋值的边的权值还小,就进行更改
{
T[i].weight=w;
T[i].from=j;///那么进行更改,它的起点也就要赋值成j
}
}
}
}
///输出
void print(Edge *T)
{
int i,s=0;
printf("最终生成树:\n");
for(i=1;i<n;i++)
{
s+=T[i].weight;///累加
printf("%c->%c %d\n",T[i].from+'A'-1,T[i].to+'A'-1,T[i].weight);
}
printf("成本为:%d\n",s);
}
#include<stdlib.h>
#include<string.h>
#define MAX 100
#define MAXSIZE 10000
typedef int adjmatrix[MAX][MAX];///定义一个邻接矩阵
typedef struct node///边的结构体,也就是边的信息
{
int from,to;///树的起点和终点
int weight;///数的权值
}Edge;
int arcnum,n;///arcnum是边的数量,n是顶点的个数,我定义在全局变量就不需要去再传递参数了
void creat_matrix(adjmatrix G);///创建邻接矩阵
void prim(adjmatrix G,Edge *T);///利用prim算法从出发点求邻接矩阵表示的图的最小生成树
void print(Edge *T);///输出
int main()
{
adjmatrix G;///定义一个邻接矩阵
Edge T[MAX];///T就是最小生成树
printf("请输入有顶点数:");
scanf("%d",&n);///顶点数
creat_matrix(G);///创建邻接矩阵
prim(G,T);///prim算法
print(T);///输出路径和最小成本
return 0;
}
///创建邻接矩阵
void creat_matrix(adjmatrix G)
{
int i,j,k,e;
char x,y;
for(i=1;i<=n;i++)///初始化矩阵
{
for(j=1;j<=n;j++)
if(i==j)
G[i][j]=0;///对角线,也就是它本身初始化为0
else
G[i][j]=MAXSIZE;///如果不是,都是先初始化一个很大的值
}
printf("请输入边的个数:");
scanf("%d",&arcnum);
printf("起点 终点 权值:\n");
for(k=1;k<=arcnum;k++)///给每个边进行赋值
{
scanf(" %c %c %d",&x,&y,&e);///这里我定义是字符类型,%c是会读取回车键的,所以我在前面空格一下
i=x-'A'+1;///A相当于是位置1,赋值到矩阵就得相应转换成整型,不再是字符型
j=y-'A'+1;///类似
G[i][j]=e;///这是双向的,i->j的路径长度为e
G[j][i]=e;///这是双向的,j->i的路径长度为e
}
}
///利用prim算法从出发点求邻接矩阵表示的图的最小生成树
void prim(adjmatrix G,Edge *T)
{
int i,j,k,min,u,w,m;
Edge t;///暂时的
k=1;
for(i=1;i<=n;i++)///初始化T的结构体信息,首个顶点指向各个顶点
{
if(i!=1)///要那样的话就不能是i=1了 所以有了这个条件
{
T[k].from=1;///出发点都是1
T[k].to=i;///然后1出发到每个顶点
T[k].weight=G[1][i];///然后把1到各个顶点的权值赋值到T里面
k++;///然后自增
}
}
for(k=1;k<n;k++)///只要进行n-1次操作就行了
{
min=MAXSIZE;///先给min赋值一个很大的值,那么我接下来有进行比较最小,最小的值就会进行更新,这样比较方便
m=k;///m是这个是现在操作的这个顶点,用另外一个遍历是为了不改变k的值,影响到循环的遍历
for(j=k;j<n;j++)///从k之后以及k进行比较,找到这其中最小的
{
if(T[j].weight<min)///一直更新最小值,直到结束
min=T[j].weight,m=j;///m=j是最小值的位置,下面要进行再次的比较
}
t=T[k];///t就暂时的,T[k]就是最开始的信息,那么我找到了最小值的位置之后就要进行改变,把最小值的信息赋值到k的位置
T[k]=T[m];///就是变换
T[m]=t;
j=T[k].to;///新增加最小生成树T中的顶点序号赋给j
for(i=k+1;i<n;i++)///修改相关的边,就得让T中以及T外的每个顶点保持一条到现在最短的边
{
u=T[i].to;///u就是这个j所指向的顶点
w=G[j][u];///然后这个w就是代表j->u的权值,也就是接下来的每条边的权值
if(w<T[i].weight)///如果比之前所赋值的边的权值还小,就进行更改
{
T[i].weight=w;
T[i].from=j;///那么进行更改,它的起点也就要赋值成j
}
}
}
}
///输出
void print(Edge *T)
{
int i,s=0;
printf("最终生成树:\n");
for(i=1;i<n;i++)
{
s+=T[i].weight;///累加
printf("%c->%c %d\n",T[i].from+'A'-1,T[i].to+'A'-1,T[i].weight);
}
printf("成本为:%d\n",s);
}