#include "stdio.h"
#define MAX 10
#define INF 999
typedef struct Mgraph
{
int n; //图的顶点个数
int edge[MAX][MAX]; //图中边的权值
}Mgraph;
int dist[MAX]; //dist[vi]表示当前其找到的v0到每个终点vi的最短路径的长度
int path[MAX]; //path[vi]保存从v0到vi最短路径上的前一个顶点,相当于一个并查集
int set[MAX]; //为标记数组,set[vi]=1表示vi被并入最短路径中,否则没有
//求顶点v0到其余顶点的最短路径,结果保存在dist[]中
//路径保存在path[]中
void Dijkstra(int v0, Mgraph g)
{
int i, j;
//进行初始化
for(i=0; i<g.n; i++)
{
dist[i] = g.edge[v0][i];
set[i] = 0;
if(g.edge[v0][i]>INF)
path[i] = -1;
else
path[i] = v0;
}
set[v0] = 1;
path[v0] = -1;
int min, v;
for(i=0; i<g.n; i++)
{
min = INF;
/*每次从剩余顶点中选出一个顶点,通往这个顶点的路径在通往所有剩余顶点的路径中是长度最短的*/
for(j=0; j<g.n; j++)
{
if(set[j]==0 && dist[j]<min)
{
min = dist[j]; //更新最短值
v = j; //记录顶点下标
}
}
set[v] = 1; //此顶点被并入最短路径
for(j=0; j<g.n; j++)
{
//判断顶点v加入是否会使通往顶点j的路径更短,如果出现,则改变原来的路径及长度
if(set[j]==0 && dist[v]+g.edge[v][j]<dist[j])
{
dist[j] = dist[v]+g.edge[v][j]; //改变路径长度
path[j] = v; //改变路径
}
}
}
}
//构造最优解
//v0为源点,vi为终点
void printPath(int v0, int vi, int path[])
{
if(v0==vi)
return;
printPath(v0, path[vi], path);
printf("-->%d", vi);
}
void init(Mgraph &g, int edge[][5], int n)
{
g.n = n;
int i, j;
for(i=0; i<n; i++)
for(j=0; j<n; j++)
g.edge[i][j] = edge[i][j];
}
int main(){
int n = 5;
int edge[][5]={
{1000, 10, 1000, 30, 100},
{1000, 1000, 50, 1000, 1000},
{1000, 1000, 1000, 1000, 10},
{1000, 1000, 20, 1000, 60},
{1000, 1000, 1000, 1000, 1000}
};
Mgraph g;
init(g, edge, n);
int v0;
int i, j;
printf("图的矩阵为(1000表示不可达):\n");
for(i=0; i<g.n; i++)
{
for(j=0; j<g.n; j++)
printf("%d\t", g.edge[i][j]);
printf("\n");
}
v0 = 0; //源点
Dijkstra(v0, g);
for(i=0; i<g.n; i++)
{
if(i!=v0)
{
printf("源点%d到终点%d的最短路径长为:%d, ", v0, i, dist[i]);
printf("路径为:%d", v0);
printPath(v0, i, path);
}
printf("\n");
}
return 0;
}
单源最短路径--Dijkstra
最新推荐文章于 2022-06-20 09:31:28 发布