朴素Djkstra算法
求1号点到n号点的最短路径:
进行n次迭代,每次迭代确定一个节点到1号点的最短路径,并用当前最短路径更新所有可以到达的节点,直到 到达n号节点
Djkstra初始化,1号点到1号点的距离为0,1号点到其余点距离为无穷
迭代n次后,如果n号点到1号点的最短路径不为正无穷,则存在最短路径
存图时也需要先将所有节点的边初始化为正无穷
例题AcWing 849. Dijkstra求最短路 I
题目大意:
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。
1≤n≤500
1≤m≤10^5
图中涉及边长均不超过10000。
思路:
边数远大于点数,属于稠密图,用邻接矩阵来存,朴素Djkstra算法求最短路径
Solved
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=510;
int n,m;
int a[N][N];//邻接矩阵,存稠密图(边数远大于点数)
int dist[N];//存到1号点的最短路径
bool st[N];//判断当前节点最短路径是否确定
int Djkstra()
{
//Dj初始化
memset(dist,0x3f,sizeof(dist));
dist[1]=0;
//n次迭代
for(int i=1;i<=n;i++){
//每次迭代确定一个节点到1号点的最短路径
int t=-1;//t存节点编号
for(int j=1;j<=n;j++){
//找到的第一个节点或者有节点到1号点的路径更短
//并且当前节点的最短路径未确定
if( st[j]==0 && ( t==-1 || dist[j]<dist[t]) ){
t=j;//记录该点
}
}
//目前到一号节点最短的路径确定
st[t]=1;
//用该最短路径更新所有可以到达的下个节点的最短路径,t->j;
for(int j=1;j<=n;j++){
dist[j]=min(dist[j],dist[t]+a[t][j]);
}
}
//迭代n次,如果dist[n]==0x3f3f3f3f,就到不了n点
if(dist[n]==0x3f3f3f3f) return -1;
return dist[n];
}
signed main()
{
memset(a,0x3f,sizeof(a));
cin>>n>>m;
while(m--){
int x,y,z;
cin>>x>>y>>z;
//存在重边和自环,自环不影响
//如果存在多条路径,只选最短的路径存入图中
a[x][y]=min(z,a[x][y]);
}
//Djkstra算法求出1号点到n号点的距离并返回dist[n]
cout<<Djkstra()<<endl;
return 0;
}
/*
3 3
1 2 2
2 3 1
1 3 4
3
*/