题目算法笔记p367页
dijkstra算法智能解决单源最短路径的问题,而且当边权出现负数的时候,dijkstra算法很可能会出错,这时最好使用SPFA算法
输入
6 8 0 //顶点个数,边数,起点
//顶点 顶点 边权
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3
//单元最短路径算法
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int inf=10000000;
int g[30][30];//储存节点关系和边权
bool v[30];//当前节点是否已访问
int d[30];//表示起点到其他顶点的距离,这里默认起点为 0
int n,m,start;//顶点个数,边数,起点编号
void dis(int x)
{
fill(d,d+30,inf);
d[x]=0;
for(int i=1;i<n;i++)//每次处理一个距离起点最小且未被访问的顶点,只需要n-1次,因为最后一次所有点都已经被更新了
{
int u=-1,min=inf;
for(int j=0;j<n;j++)//找到这个距离起点最小且未被访问的顶点
{
if(v[j]==false&&d[j]<min)
{
u=j;
min=d[j];
}
}
if(u==-1)return ;//当前连通块和其他剩下顶点不连通
//访问点u ,并以u为中介,更新d[]
v[u]=true;
for(int i=0;i<n;i++)
{
if(v[i]==false && g[u][i]!=inf && d[u]+g[u][i]<d[i] ) // 三:通过以点u为中介可以找出一条更短的路径 //二:顶点u到顶底i之间右边连接 //一:节点未被访问
d[i]=d[u]+g[u][i];
}
}
}
int main()
{
fill(g[0],g[0]+29*29,inf);//初始化图
scanf("%d%d%d",&n,&m,&start);
for(int i=0;i<m;i++)
{
int x,y,wi;
scanf("%d%d%d",&x,&y,&wi);
g[x][y]=wi;
g[y][x]=wi;
}
dis(start);
for(int i=0;i<n;i++)
cout<<d[i]<<endl;
}