您的位置:首页 > 其它

dijkstra算法求单源最短路径

2017-12-26 18:52 357 查看
#define MAXINT 0xfff
#define MAXSIZE 1000
#include<iostream>
#include<string>
using namespace std;

int amapBorder[MAXSIZE][MAXSIZE];
int vNum = 6;		//总共有6个顶点元素

void initmap()		//这里是无向图,初始化随便造了一个图,没有用存储图的结构,存储图的结构我其他文章里有。
{
for(int i = 1 ; i < vNum + 1 ; i++)
{
for(int j = 1 ; j < vNum + 1 ; j++)
{
amapBorder[i][j] = MAXINT;	//先初始化图的所有边都为无穷大,即没有边。
}
}

amapBorder[1][2] = 6;
amapBorder[1][3] = 3;
amapBorder[2][3] = 2;
amapBorder[2][4] = 5;
amapBorder[3][4] = 3;
amapBorder[3][5] = 4;
amapBorder[4][5] = 2;
amapBorder[4][6] = 3;
amapBorder[5][6] = 5;		//定义一部分边,并给出边权重
for(int i = 1 ; i < vNum + 1 ; i++)
{
for(int j = 1 ; j < vNum + 1 ; j++)
{
if(i == j)
{
amapBorder[i][j] = 0;	//顶点与它自身的权重肯定为0
}
if(amapBorder[i][j] == MAXINT)
{
amapBorder[i][j] = amapBorder[j][i];	//由于是无向图,所以两个顶点之间的边无论什么方向,权重一样

}
}
}
}

void dijstra(int vo)
{
int U[7] = {0} 		//初始化U数组和dist数组所有元素为0,U[]数组判断一个顶点是否已经加入得出最短距离的阵营,
int dist[7] = {0};	//dist[]存储所有顶点到给定点vo最短距离
int path[7];		//存储该顶点(数组下标)对应的上一个顶点,通过它可以递归得出到达该顶点所经过的所有顶点,连起来也就是最短路径。
/*其实总共是有6个顶点元素的,这里数组下标0没有用到,资源浪费了,不过强迫症,不想用0,渴望从1开始*/
for(int i = 1 ; i < vNum + 1 ; i++)	//vNum+1是7
{
dist[i] = amapBorder[vo][i];	//dist[i]这里保存vo-i所经距离,这时候我不知道最短距离,所以先取邻接矩阵里的信息,可能是0,可能是数字n,可能是无穷大
if(dist[i] == MAXINT)
{
path[i] = -1;	//如果是正无穷,意味着此时,vo到达不了i,没路,那么到达i所经历的最后一个顶点有吗?没有,那就给个-1吧,此路不通。

}
else
{
path[i] = vo;	//如果有路,那就正常把经过i的最后一个顶点赋给path[i],方便最后递归找路。
}
}

for(int i = 1 ; i < vNum + 1 ; i ++)
{
int minNum = MAXINT;	//选取出来dist[j]的最小值并把记录。
int temp = vo;
for( int j = 1 ; j < vNum + 1 ; j++)
{
if((!U[j]) && dist[j] < minNum )	//判断要求:此时j这个点要在没得到最小路径点的阵营里,并且这个dist[j]小于minNum
{
minNum = dist[j];		//从而筛选出最小的dist[]
temp = j;			//记录最小的dist[]所对应的顶点,j赋值给temp;
}
}
U[temp] = 1;		//temp点已找到最短距离,加入找到阵营

for(int j = 1; j < vNum + 1 ; j++)
{
if(!U[j] && amapBorder[temp][j] < MAXINT)	//判断要求:j在未找到阵营里,且temp-j有路可走,其实有路可走不判断也行,主要害怕MAXINT这个数太大跟dist[temp]相加溢出。
{
if(dist[j] > amapBorder[temp][j] + dist[temp])	//如果vo到temp的距离(最短距离)+ temp到j的距离 比原来vo直接到j距离短,则更新dist[j]
{
dist[j] = amapBorder[temp][j] + dist[temp];
path[j] = temp;		//记录path[j]经过的最后一个点,至少当前这个点事temp,以后可能还要变。
}
}
}
}

for(int i = 1; i < vNum + 1 ; i++)	//打印vo到各个顶点最短距离,以及路径
{
cout << i << ":	" << dist[i] << '\t';
int j = i;
cout << j << "<-";
while(path[j] != vo)	//递归path[]找出到一个顶点经过的所有顶点,倒序列出来,当然可以转换为正序。
{
j = path[j];
cout << j << "<-";
}
cout << vo << endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息