Dijkstra算法求有权图的单源最短路,下面直接给出模板。
测试数据:
6 8
1 3 10
1 5 30
1 6 100
2 3 5
3 4 50
4 6 10
5 6 60
5 4 20
输出数据:
起点 终点 最短路径 长度
v1 v2 无 ∞
v3 {v1,v3} 10
v4 {v1,v5,v4} 50
v5 {v1,v5} 30
v6 {v1,v5,v4,v6} 60
#include <iostream>
#include <cstring>
#define MAX 100
using namespace std;
int map[MAX][MAX];
int path[MAX];
bool vis[MAX];
int dis[MAX]; //dis[i]表示源点到i点的距离最小值
int N;
void Dijk(int s)
{
path[s] = -1; //初始结点路径设为-1,作为递归终点
memset(dis,0x3f,sizeof(dis)); //dis初始化为无穷大
dis[s] = 0;
while(1)
{
int k = 0;
for(int j = 1;j <= N;j++)
{
if(!vis[j] && dis[k] > dis[j]) //找不在vis并且从原点到该顶点距离(dis[k])最小的顶点
k = j;
}
if(!k) return; //没找到,表示vis集合收录了所有的顶点,退出循环
vis[k] = 1; //收录该顶点
for(int j = 1;j <= N;j++) //比较顶点k出度的距离(dis[k]+map[k][j])与原dis,更新dis
{
if(dis[j] > dis[k] + map[k][j]) //map[k][j]不为无穷大表示顶点k的出度
{
dis[j] = dis[k] + map[k][j];
path[j] = k; //存储路径,j的父结点为k
}
}
}
}
void print(int x) //打印路径
{
if(x == -1) return;
print(path[x]);
cout<<x<<endl;
}
int main()
{
int M;
int x, y, z;
cin>>N>>M; //N个顶点,M条边
memset(map,0x3f,sizeof(map)); //此为初始化无穷大的方法,int占4个字节,每个字节都赋为0x3f,加起来就是0x3f3f3f3f
while(M--)
{
cin>>x>>y>>z; //X顶点和Y顶点的权为z
map[x][y] = z;
// map[y][x] = z; 无向图加上这一行
}
Dijk(1); //表示源点1到其他任意顶点的最短路
int p; //指定终点
while(cin>>p)
{
if(dis[p] == 0x3f3f3f3f) //0x3f3f3f3f (4个3f,值为1061109567,10^9次方级别,可定义为无穷大)
{
cout<<"该顶点无路径!"<<endl;
}
else
{
print(p);
cout<<"长度为:"<<dis[p]<<endl;
}
}
return 0;
}