#include <stdio.h>
//max表示点,边的最大个数
#define max 1000
//wq表示两点的距离为无穷
#define wq 9999
//邻接矩阵存储相应的边的权重
int mix[max][max];
//输入并构造邻接矩阵
void input(int n,int m)
{
int i,j,sp,ep,wg;
//初始化邻接矩阵每个都是无穷大
for (i=0;i<n;i++)
for (j=0;j<n;j++)
mix[i][j]=wq;
printf("请输入边的起点、终点、权重(EX:1 2 3):/n");
for (i=0;i<m;i++)
{
scanf("%d %d %d",&sp,&ep,&wg);
//无向连通图
mix[sp][ep]=wg;
mix[ep][sp]=wg;
}
}
//显示邻接矩阵
void output(int n,int m)
{
int i,j;
printf("/n邻接矩阵如下:/n/n");
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
printf("%d/t",mix[i][j]);
printf("/n");
}
}
//prim算法实现
void prim(int n,int r)
{
//a[max]用来存放各个点到已经标记点的集合的最短距离
int a[max];
//b[max]用来记录每个点的标记状态,false表示还没标记。
bool b[max];
int i,j,k,min;
//初始化从根节点开始
for (i=0;i<n;i++)
{
a[i]=mix[r][i];
b[i]=false;
}
b[r]=true;
printf("/n依次被标记的点及相应边的权重:/n");
printf("%d/t%d/n",r,0);
for (i=0;i<n-1;i++)//还剩n-1个点
{
k=0;
min=wq;
for (j=0;j<n;j++)
{
//第j个点到已经标记点的集合的距离最小且这个点还没有被标记
//k记录下一个将被标记的点
if (a[j]<min&&b[j]==false)
{
min=a[j];
k=j;
}
}
b[k]=true;//标记节点k
printf("%d/t%d/n",k,min);
//更新a[]里的状态,时刻保持最新的状态
//存放各个点到已经标记点的集合的最短距离
for (j=0;j<n;j++)
{
if (mix[k][j]<a[j])
{
a[j]=mix[k][j];
}
}
}
}
int main()
{
//n是点的个数 ,m是边的个数
int n,m,r;
printf("请输入点的个数和边的个数(EX:1 3):/n");
scanf("%d %d",&n,&m);
//输入并构造邻接矩阵
input(n,m);
//显示邻接矩阵
output(n,m);
while (1)
{
printf("/n请输入根节点(-1跳出):/n");
scanf("%d",&r);
if(r==-1)
break;
//prim算法实现
prim(n,r);
printf("/n/n");
}
return 0;
}