蒂克斯特拉算法:(固定起点到任意终点的最短路径。)
处理的最短路类型: 单源(固定起点)的图上的权值是非负数的有向图和无向图(一个无向边相当于有两个有向边)。
基本思想: 如果v0到u的最短路径经过v1,那么v0到v1的路径也是v0到u的最短路径。(所以求v0到v1的最短路径,先求v0到
u的最短路径)。
处理方法: (1)求出v0为源点长度最短的一条路径(与v0直接相连的路径)。
(2)求出此时的顶点到各个直接相连的顶点的最短路径,并更新各顶点的最短路径。
(3)重复(2)直到丛顶点v0到其他各定点的最短路径全部求出来为止。
#include <iostream>
using namespace std;
const int MAXN = 1000000 ;
int dist[10] ; //固定源点到各个顶点的最短路径
int s[10] ; // 标记是否找已经找出了最短路径。是标记为1(就是每次找出最短路径的顶点)
int path[10] ; // 固定源点到各个顶点的最短路径的路径
int n , m ;
int edge[10][10] ;
void init() //初始化s ,edge , path
{
for(int i = 0; i < n; i ++)
s[i] = 0 ;
s[0] = 1 ;
int x , y , value ;
for(int i = 0; i < n; i ++)
for(int j = 0; j < n; j ++)
if(i == j) edge[i][j] = 0 ;
else
edge[i][j] = MAXN ;
for(int j = 0; j < m; j ++)
{
cin >> x >> y >> value ;
edge[x][y] = value ;
}
for(int i = 0; i < n; i ++)
dist[i] = edge[0][i] ;
for(int i = 0; i < n; i ++)
if(edge[0][i] < MAXN && i != 0)
path[i] = 0 ;
else
path[i] = -1 ; //到达v0的最短路径是他本身,所以设为-1。
}
void dijstra()
{
int little = MAXN ;
int u ;
for(int i = 0; i < n; i ++)
if(s[i]!=1 && little > dist[i]) //求所有顶点的最短路径。
{
little = dist[i] ;
u = i ;
}
s[u] = 1 ;
for(int i = 0; i < n; i ++)
if(!s[i] && edge[u][i]!=MAXN && dist[i] > edge[u][i] + dist[u])
{
dist[i] = dist[u] + edge[u][i] ; // 求此时的顶点到相连的下一个顶点的最短路径。
path[i] = u ;
}
int flag = 0 ;
for(int i = 0; i < n; i ++)
if(s[i] == 0) flag = 1 ;
if(flag) dijstra() ;
}
int main()
{
cin >> n >> m;
init() ;
dijstra() ;
cout << "s" << endl ;
for(int i = 0; i < n; i ++)
cout << dist[i] << endl;
cout << "path" << endl;
for(int i = 0; i < n; i ++)
cout << path[i] << endl;
cout << "path[4]:" << path[4] << endl ;
int i = 4 ;
while(i)
{
cout << path[i] << endl ;
i = path[i] ;
}
return 0 ;
}