最短路径:一个源点到图中每个顶点的距离。在实现这个的时候,构建的是一个有向图。我们先看看算法的大致思想:
(1)带权邻接矩阵arcs来表示带权有向图,若<vi,vj>不存在,则置其权值为最大值。
(2)选择vj,使得D[j] = Min{D[i],该元素未加入最短路径集合}
(3)修改从v出发到那个未处理集合的顶点的最短路径。D[j] + arcs[j][k] < D[k].更新这个距离,直至最短距离不发更新。
我在实现这个的时候,遇到一些细节问题:在这个图中可能存在不可达点,所以有时可以提前结束最短路径的算法,在更新路径的时候,你会发现当更新一个不可达点时,会出现负数,这就是计算机的数据溢出造成的,所以在处理的时候,需要在更新的时候过滤掉不可达点。
#include "graph.h"
#include <stdio.h>
//#define DEBUG
/*********************************************/
/* 最短路径算法 */
/* 参数:G 开始点 */
/* 功能 */
/*********************************************/
void ShortestPath_DIJ(const MGraph *g,const int v0)
{
int closedge[MAX_VERTEX_NUM]; //存储v0到每个节点的最短路径权值
bool colored[MAX_VERTEX_NUM]; //标记该节点是否处理过
int i;
//得到起始点邻接的点权值
//不邻接的都是最大值
for(i=0;i<g->vexnum;i++)
{
closedge[i] = g->arcs[v0][i];
colored[i] = false;
}
#ifdef DEBUG
for(i=0;i<g->vexnum;i++)
printf("%d ",closedge[i]);
printf("\n");
#endif
//值为0表明该点已加入树
closedge[v0] = 0;
colored[v0] = true;
//逐渐构建最短路,每次加入一个点
//注意存在不可达点。。
int vtemp = -1;
while(v0 != vtemp)
{
int temp = INT_MAX; //记录最小权值
vtemp = v0; //记录将加入点
//查找到最小权值点
for(i=0;i<g->vexnum;i++)
{
if((!colored[i])&&(temp > closedge[i]))
{
temp = closedge[i];
vtemp = i;
}
}
// printf("The node[%d]:%d\n",vtemp,temp);
//由于加入新节点,所以改变每个节点到v0的值
for(i=0;i<g->vexnum;i++)
{
if(g->arcs[vtemp][i] != INT_MAX) //过滤不可达点
if(closedge[i] > (closedge[vtemp] + g->arcs[vtemp][i]))
{
closedge[i] = g->arcs[vtemp][i] + closedge[vtemp];
}
}
colored[vtemp] = true; //设置为加入点
#ifdef DEBUG
for(i=0;i<g->vexnum;i++)
printf("%d ",closedge[i]);
printf("\n");
#endif
}
for(i=0;i<g->vexnum;i++)
printf("%d ",closedge[i]);
printf("\n");
}
/*test
6 8
0 1 2 3 4 5END
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 20
4 5 60
end*/
最短路径的实现
最新推荐文章于 2022-09-24 14:03:02 发布