学习"图"(最短路径)算法

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到底变了没有?

让我们来调试一下:

 

未标题-1

未标题-2

现在来看看下面的一个for(k)是干什么的。。

未标题-3

未标题-5

未标题-6

大功告成!OK。。。

posted @ 2012-01-21 19:00  Ю詺菛╀時代  阅读(749)  评论(0编辑  收藏  举报