背景及代码原理讲解链接: https://blog.csdn.net/qq_44394952/article/details/122260015?spm=1001.2014.3001.5501.
#include<stdio.h>
#include<stdlib.h>
#define INF 100 //不相邻的两个节点,采用相对较大的100来代替路径长度
struct Cost{ //Cost结构体
int Dis;
};
Cost **creat(int n,int m)//创建存储结构
{
printf("依次输入每两个相连结点及其之间的路径长度:\n");
int i,j,c,n1,n2;
Cost **a;
a=(Cost**)malloc(sizeof(Cost*)*n);
for(i=0;i<n;++i)
{
a[i]=(Cost*)malloc(sizeof(Cost)*n);
}
for(i=0;i<n;++i) //初始化
for(j=0;j<n;++j)
{
if(i==j)
{
a[i][j].Dis=0; //起止点相同的点距离设为0
}
else
{
a[i][j].Dis=INF; //起止点不同的点距离设为无穷
}
}
for(i=0;i<m;++i) //录入结点及距离
{
scanf("%d %d %d",&n1,&n2,&c);
a[n1][n2].Dis=c;
a[n2][n1].Dis=c;
}
printf("\n");
printf("输出的结点间路径长度的矩阵为:\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d ",a[i][j].Dis);
}
printf("\n");
}
return a;
}
void minPath(Cost *a[],int s,int d,int n) //最短路径
{
int i,j,c=d;
int visit[n],len[n],path[n],path1[n];
for(i=0;i<n;i++) //初始化,直接相邻设为两点间路径长度,不相邻设为无穷
{
visit[i]=0; //标记是否访问该点
len[i]=a[s][i].Dis;
if(len[i]!=INF) //记录路径信息
path[i]=s;
else
path[i]=INF;
}
for(i=0;i<n;++i)
{
int min_dis=INF;
int pos;
for(j=0;j<=n;++j) //找出未标记的路径长度最小的点
{
if(!visit[j]&&min_dis>len[j])
{
pos=j;
min_dis=len[j];
}
}
visit[pos]=1;
for(j=0;j<=n;++j) //通过标记点计算起始点与未标记点的最近距离
{
if(!visit[j]&&(len[j]>(len[pos]+a[pos][j].Dis)))
{
len[j]=len[pos]+ a[pos][j].Dis;
path[j]=pos;
}
}
}
if(len[d]<100000) //如果连通则输出路径和路径长度
{
i=0;
while(1)
{
path1[i]=c;
++i;
c=path[c];
if(c==s)break;
}
path1[i]=s;
printf("\n");
printf("路径:"); //输出路径
printf("%d",path1[i]);
for(;i>0;--i)
{
printf("-->");
printf("%d",path1[i-1]);
}
printf("\n");
printf("距离:%d ",len[d]);
printf("\n");
}
else printf("两结点不连通!!");
}
//主函数
int main()
{
int n,m,s,d,c;
printf("输入结点数量以及节点间路径数量:");
scanf("%d %d",&n,&m);
printf("\n");
Cost **a;
a=creat(n,m);//建立邻接矩阵
n=n+1;
printf("\n");
//情况1:输出给定起始结点和目的结点的路径和距离
printf("输入起始结点和目的结点:");
scanf("%d %d",&s,&d);
minPath(a,s,d,n);//最短路径
printf("\n");
printf("\n");
//情况2:输出以v0为起始结点,其余各点为目的结点的全部路径和距离
for(s=0,d=1;d<=6;d=d+1)
{
printf("起始结点为%d,目的结点为%d",s,d);
minPath(a,s,d,n);//最短路径
printf("\n");
}
return 0;
}