这里更多算法(更好的阅读体验)
dijkstra最短路算法
算法过程(不包含初始化)
- 从起点s开始,更新相连节点距离(其实就是如果有直接距离就更新直接距离)
- 将起点s标记为 “已访问过”
- 在“未访问的节点”上寻找离起点最近的节点pos(相当于 1. 的起点)
- 将节点pos标记为“已访问过”
- 寻找 与节点pos相连(有路径)的、未被标记为“已访问过”的 节点j,并更新节点j到初始节点最近距离
- 重复 3. 4. 步骤
- 直到所有的节点都被标记为“已访问过”,跳出循环
- 输出距离
代码实现(链式前向星 + dijkstra)
链式前向星此代码不详解
#include <bits/stdc++.h>
using namespace std;
//我不编译所以变量名直接用简洁明了的意思了
const int N = 节点数 + 5, M = 边数 + 5, ma = INT_MAX;
//加5是为了防止数据溢出导致RE
struct Edge{
int to, cost, next;
};
Edge e[M * 2];
int head[N], ans[N], cnt = 1;
// 头节点集合 最短距离
bool flag[N];//是否被标记过
void add(int from, int to, int cost){
e[cnt].to = to;
e[cnt].cost = cost;
e[cnt].next = head[from];
head[from] = cnt;
cnt ++;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
//大数据输入输出优化
freopen("xxx.in", "r", stdin);
freopen("xxx.out", "w", stdout);
//读入文件类型数据(比赛用)
int n, m, s;//n 节点数 m 边数 s 初始节点
cin >> n >> m;
for(int i = 1; i <= m; ++ i){
int x, y, z;
cin >> x >> y >> z;
add(x, y, z);
add(y, x, z);
//存双向边
}
//以下为初始化过程
for(int i = 1; i <= n; ++ i)
ans[i] = ma;
//将每个节点到初始节点的距离设为无穷大,方便更新答案
for(int i = head[s]; i; i = e[i].next)
ans[e[i].to] = e[i].cost;
//步骤1
ans[s] = 0;//初始节点到初始节点的距离为0
flag[s] = true;
//步骤2
while(1){
//步骤 6
int tmp = ma, pos = s;
for(int i = 1; i <= n; ++ i)
if(!flag[i] && tmp > ans[i]){
tmp = ans[i];
pos = i;
}
//步骤3
if(pos == s) break;
//步骤7
flag[pos] = true;
//步骤4
for(int i = head[pos]; i; i = e[i].next)
if(![e[i].to] && ans[e[i].to] > ans[pos] + e[i].cost)
ans[e[i].to] = ans[pos] + e[i].cost;
//步骤5
}
for(int i = 1; i <= n; ++ i)
cout<< ans[i] << " ";
//步骤8
return 0;
}