伪代码(出自刘汝佳的《算法竞赛入门经典第2版》):
清除所有点的标号
设d[0]=0, 其他d[i]=INF//INF被定义为一个很大的数字
循环n次 {
在所有未标号结点中,选出d值最小的结点x
给结点x标记
对于从x出发的所有边(x,y),更新d[y] = min{d[y], d[x]+w(x,y)}
//w(x,y)是指边xy对应的权值
}
我采用了邻接矩阵
本渣渣的代码:
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1007;
int dis[maxn], mp[maxn][maxn], n;
bool vis[maxn];
void init() {
for (int i=1;i<=n;i++) {
dis[i] = INF;
vis[i] = false;
for (int j=1;j<=i;j++) {
if (i == j) {
mp[i][j] = mp[j][i] = 0;
} else {
mp[i][j] = mp[j][i] = INF;
}
}
}
}
void dijkstra(int s) {//计算s到所有点的最短路,结果保存在dis数组中
dis[s] = 0;
for (int i=1;i<=n;i++) {
int p = 0, minn = INF;
for (int j=1;j<=n;j++) {
if (!vis[j] && dis[j] < minn) {//从未访问过的节点中,选出dis最小的节点p
minn = dis[j];
p = j;
}
}
vis[p] = true;//标记p访问过
for (int j=1;j<=n;j++) {//对所有从p出发的到达j,且j未被访问过,更新dis,确保dis中存储起点到j的最小花费
if (!vis[j]) {
dis[j] = min(dis[j], dis[p] + mp[p][j]);
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
int m, x, y, d;
cin>>n;
init();
cin>>m;
for (int i=1;i<=m;i++) {
cin>>x>>y>>d;
mp[x][y] = mp[y][x] = d;
}
dijkstra(2);
for (int i=1;i<=n;i++) {
cout<<dis[i]<<" ";
}cout<<endl;
return 0;
}