学习"图"(最短路径)算法
1、首先上图哈:图的邻接矩阵表示。
2、图的最短路径
#include<stdio.h>
#define MAX 10000
#define N 6
//每个定点到其它顶点的直线距离
int G[N][N]=
{
{MAX,MAX,10,MAX,30,100},
{MAX,MAX,5,MAX,MAX,MAX},
{MAX,MAX,MAX,50,MAX,MAX},
{MAX,MAX,MAX,MAX,MAX,10},
{MAX,MAX,MAX,20,MAX,60},
{MAX,MAX,MAX,MAX,MAX,MAX}
};
//p表示到达这个点的最短距离路径上的节点
int p[N][N] =
{
//先给他们初始状态
//v0到v可通的就将其下标存起来
//v0->v0没意义
{0,0,0,0,0,0},
//v0->v1不可通
{0,0,0,0,0,0},
//v0->v2可通,
{0,2,0,0,0,0},
{0,0,0,0,0,0},
{0,4,0,0,0,0},
{0,5,0,0,0,0}
};
void main(){
//定义距离数组,把求出来的
//v0到其它点的最短距离都存放在这里。
int d[N] = {MAX,MAX,10,MAX,30,100};
//要计算v0到每个点的最短距离
//方法:遍历除v0之外的所有顶点N遍(最外层i循环),
//每一遍都找出一个最短距离和经过这个顶点的间接最短距离
//并且赋值到相应的距离里去。
//如果能取出比他更短的,否则就以其原来作为最短距离
int flag[N] = {0};
int i,v,min,k,j;
//一共循环N次
for(i=0;i<N;i++){
//首先找出v0出发直线距离最短的
//min存储了v0到其它点的最短距离
//v存储了最短距离对应的顶点。
for(k=0,min = MAX,v = 0;k<N;k++){
if(flag[k] != 1 && d[k]<min){
min = d[k];
v = k;
}
}
//将这个最短距离存到v对应的节点里去
d[v] = min;
//已经算出最短距离的标志为1
//在其它循环当中进行排除。
flag[v] = 1;
//开始求间接距离最短
for(k=0;k<N;k++){
//还没有求出最短距离,
//且原来最小的v0到v的直线距离
//值加上v到k的距离要比直线距离来的小
//说明d[k] 有更小的了。
if(flag[k] != 1 && min + G[v][k]<d[k]){
d[k] = min + G[v][k];
//有些顶点是经过了两个或多个中间节点的
//所以要把p[k][0]作为标志
if(p[k][0] == 0){//如果没设置过
p[k][0] = 1;
//是经过v到达k的,所以:
p[k][1] = v;
p[k][2] = k;
}else{//如果设置过了
for(j=1;p[v][j];j++)
p[k][j] = p[v][j];
p[k][j] = k;
}
}
}
}
//打印出距离
for(i=0;i<N;i++)
printf("%5d",d[i]);
printf("\n");
//打印最短距离经过的节点
for(i=1;i<N;i++){
printf("v0->v%d:::",i);
for(j=1;j<N;j++)
printf("%5d",p[i][j]);
printf("\n");
}
getchar();
}
我们可以看下运行的结果
是不是还不理解外层循环到底做了什么?
v到底变了没有?
让我们来调试一下:
现在来看看下面的一个for(k)是干什么的。。
大功告成!OK。。。









浙公网安备 33010602011771号