相关blog:【图】最短路径Dijkstra算法C语言实现
1.算法过程:
1.把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则 G [ i ] [ j ] = d G[i][j]=d G[i][j]=d, d d d表示该路的长度;否则 G [ i ] [ j ] = ∞ G[i][j]=∞ G[i][j]=∞。一个点到自己的距离如 G [ i ] [ i ] = 0 G[i][i]=0 G[i][i]=0
2.定义一个矩阵D用来记录所插入点的信息,
D
[
i
]
[
j
]
D[i][j]
D[i][j]表示从
V
i
Vi
Vi到
V
j
Vj
Vj需要经过的点,初始化
D
[
i
]
[
j
]
=
−
1
D[i][j]=-1
D[i][j]=−1。
3.把各个顶点插入图中,比较插点后的距离与原来的距离,
G
[
i
]
[
j
]
=
m
i
n
(
G
[
i
]
[
j
]
,
G
[
i
]
[
k
]
+
G
[
k
]
[
j
]
)
G[i][j] = min( G[i][j], G[i][k]+G[k][j] )
G[i][j]=min(G[i][j],G[i][k]+G[k][j]),如果
G
[
i
]
[
j
]
G[i][j]
G[i][j]的值变小,则
D
[
i
]
[
j
]
=
k
D[i][j]=k
D[i][j]=k(记录中间结点)。在
G
G
G中包含有两点之间最短道路的信息,而在
D
D
D中则包含了最短通路径的信息。
比如,要寻找从V5到V1的路径。根据D,假如 D ( 5 , 1 ) = 3 D(5,1)=3 D(5,1)=3则说明从V5到V1经过V3,路径为 V 5 , V 3 , V 1 {V5,V3,V1} V5,V3,V1,如果 D ( 5 , 3 ) = 3 D(5,3)=3 D(5,3)=3,说明V5与V3直接相连,如果 D ( 3 , 1 ) = 1 D(3,1)=1 D(3,1)=1,说明V3与V1直接相连。
4. D D D即为所有点对的最短路径矩阵
5.得到最短路径矩阵后,若 p a t h [ i ] [ j ] = − 1 path[i][j]=-1 path[i][j]=−1,表示此路通,可以直接输出,否则, i , j i,j i,j不直接相通,第一个中间结点 m i d = p a t h [ i ] [ j ] mid=path[i][j] mid=path[i][j],继续将 p a t h [ i ] [ m i d ] path[i][mid] path[i][mid]和 p a t h [ m i d ] [ j ] path[mid][j] path[mid][j]递归求解.
2.代码:
#include<stdio.h>
#define SIZE 110
#define INF 1000000
int sum=0;
void Floyd(int n,int Graph[][SIZE],int path[][SIZE])//求最短路径矩阵path[][]
{
int i,j,k;
int A[SIZE][SIZE];
for(i = 0;i < n;i++)
{
for(j = 0;j < n;j++)
{
A[i][j] = Graph[i][j];
path[i][j] = -1;
}
}
for(k = 0;k < n;k++)
{
for(i=0;i < n;i++)
{
for(j=0;j < n;j++)
{
if(A[i][j]>A[i][k]+A[k][j])
{
A[i][j] = A[i][k]+A[k][j];
path[i][j] = k;
}
}
}
}
}
int gen(int map[SIZE][SIZE],int start ,int end)//图的建立
{
int vertex;
int i,j;
int k;
int Ver;
int edge_num;
scanf("%d%d",&vertex,&edge_num);
for(i=0;i<=vertex;i++)
{
for(j=0;j<=vertex;j++)
if(i == j)
{
map[i][j] = 0;
}
else
{
map[i][j] = INF;
}
}
for(k=0;k<edge_num;k++)
{
scanf("%d%d",&i,&j);
scanf("%d",&map[i][j]);
//map[j][i]=map[i][j];
}
return vertex;//返回顶点数目
}
void shortpath(int start,int end,int path[][SIZE],int Graph[][SIZE])//打印最短路径
{
if(path[start][end] == -1)
{
printf("<%d,%d>",start,end);
sum = sum+Graph[start][end];
}
else
{
int mid = path[start][end];
shortpath(start,mid,path,Graph);
shortpath(mid,end,path,Graph);
}
}
int main () {
int Graph[SIZE][SIZE];
int path[SIZE][SIZE];
int start,end;
scanf("%d%d",&start,&end);//记录出发点和目的地
int vertexnum = gen(Graph,start,end);
Floyd(vertexnum,Graph,path);
shortpath(start,end,path,Graph);
printf("\n%d",sum);
return 0;
}
3.测试:
输入:
1 0//从1到0的最短路径
4 8//四个顶点八条边
0 1 5
0 3 7
1 2 4
1 3 2
2 0 3
2 1 3
2 3 2
3 2 1
输入的后8行相当于
map[0][1] = 5; //测试数据
map[0][3] = 7;
map[1][2] = 4;
map[1][3] = 2;
map[2][0] = 3;
map[2][1] = 3;
map[2][3] = 2;
map[3][2] = 1;
输出:
<1,3><3,2><2,0>//轨迹
6 //最短路径
相关blog:【图】最短路径Dijkstra算法C语言实现