因为这是两点之间的最小路径问题(即单源最短路径问题)所以用深度或广度遍历进行查找较方便。
采用深度遍历查找(代码+解析)如下:结合代码进行解析和结合图进行理解较容易。
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
//not_c 表示的是没有关系的值
#define not_c 10000
//图的结构
struct Chart{
int bian_sum;
int spot_sum;
int connection[MAX][MAX];
};
typedef struct Chart *tu;
//边的结构
struct Bian{
int left,right;
int value;
};
typedef struct Bian *bian;
//访问标志
int visit[MAX];
//最短的路径以及从哪到哪个顶点
int minpart= not_c;//默认是not_c当没有找到最小路径时即两个点没有关系时的值
int spot_left;
int spot_right;
void chazhao(tu chart,int now_spot,int now_value);
tu creater(int dian);
int main(){
int dian;
printf("请输入顶点的个数:");
scanf("%d",&dian);
tu chart;
//初始化图:即创建一个没有边的图
chart=creater(dian);
//创建边
bian tran;
tran=(bian)malloc(sizeof(struct Bian));
//创建有边的图,该题是有有向图
printf("请输入边的个数:");
scanf("%d",&chart->bian_sum);
for(int i=0;i<chart->bian_sum;i++){
printf("请输入从哪个点到哪个点和之间的权值:");
scanf("%d%d%d",&tran->left,&tran->right,&tran->value);
//创建
chart->connection[tran->left][tran->right]=tran->value;
}
printf("请输入你要查找哪两个顶点的最短的路径:");
scanf("%d%d",&spot_left,&spot_right);
//将开始位置进行标记
visit[spot_left]=1;//因为执行函数里面不是到某个结点就进行标记
//第一次进入的是开始的位置和当前走过的权值为0
chazhao(chart,spot_left,0);//利用深度优先遍历执行。作为参数进入的是图和当前的结点和走到当前结点的权值
//执行结束将查找到的最小的路径进行输出
printf("从%d到%d的最小的权值为:%d",spot_left,spot_right,minpart) ;
}
tu creater(int dian){
tu head;
head=(tu)malloc(sizeof(struct Chart));
head->bian_sum=0;
head->spot_sum=dian;
for(int i=1;i<=dian;i++){
for(int j=1;j<=dian;j++){
head->connection[i][j]=not_c;
}
head->connection[i][i]=0;//我们讲的图斗是简单图(即自己和自己是没有边的)
//赋0表示是自己的位置
}
return head;
}
//用深度优先遍历进行查找
void chazhao(tu chart,int now_spot,int now_value){
if(now_value>=minpart)//这里是判断走到当前结点的权值有没有已经大于我上一次找到的最小权值。如果已经大于等于说明再往该路径走阴茎没有意义
return;//不执行下面的程序
//判断是不是走到我要找的结点的位置了
if(now_spot==spot_right){
if(minpart>now_value){
minpart=now_value;
return;//不执行下面程序
}
}
for(int i=1;i<=chart->spot_sum;i++){
if(visit[i]==0&&chart->connection[now_spot][i]!=0&&chart->connection[now_spot][i]!=not_c){
visit[i]=1;//表示当前位置
//调用的权值是上一次走到当前位置的权值加上从当前位置走到下一次位置的权值
chazhao(chart,i,now_value+chart->connection[now_spot][i]) ;
//执行完后变为没有访问过的
visit[i]=0;
//一定要理解这里为什么要变为没有访问过的;
//理解:将下一个结点标志为没有访问过的:
//因为我们要找进行各种路径的寻找,只有再执行完后标志为没有访问过的才能在下次时也能访问该结点(画图即可理解)
}
}
}
结果如下: