dijkstra的堆优化(最简版本)
先了解不用堆优化的dijkstra:https://blog.csdn.net/weixin_43828245/article/details/90722389
推荐视频讲解(代码是Python写的,重点听思路):https://www.bilibili.com/video/av25829980
了解c++优先队列:https://blog.csdn.net/weixin_43828245/article/details/90742490
直接放代码,详见注释
#include <iostream>
#include <queue>
#include <cstring>
#define inf 0x3f3f3f
using namespace std;
typedef struct node {
int v,date;
} ty;
bool operator < ( const ty &a, const ty &b ) // 自定义优先队列规则,先pop出小的来
{
return a.date>b.date; // 这里和sort相反,a>b是先pop出小的
}
int a[2002][2002];
int via[2002]; // 判断是否已经pop出来了
int dis[2002]; // 存放距离
int i,j,n,m;
ty t,d;
void dijkstra( int v0 )
{
priority_queue <ty> Q; // 自定义的优先队列
memset(dis,inf,sizeof(dis)); // 初始化dis为inf,避免和v0相连的点不能进入队列
dis[v0] = 0;
t.v = v0;
t.date = 0;
Q.push(t); // 先将顶点入队
while ( !Q.empty() ) {
if ( via[Q.top().v]==1 ) { // 如果队列的点已经弹出过了,那么舍弃这个点
Q.pop();
continue ;
}
t = Q.top();
Q.pop();
int u = t.v;
via[u] = 1;
dis[u] = t.date; // 对于弹出来的点,就是已经做好了的点
for ( i=1; i<=n; i++ ) {
if ( via[i]==0 && a[u][i]<inf && dis[i]>dis[u]+a[u][i] ) {
dis[i] = dis[u] + a[u][i]; // 更新最短路,并存入队列
d.v = i;
d.date = dis[i];
Q.push(d);
}
}
}
cout << dis[n] << endl;
}
int main()
{
cin >> m >> n;
memset(a,inf,sizeof(a));
memset(via,0,sizeof(via));
for ( i=1; i<=n; i++ ) {
a[i][i] = 0;
}
for ( i=1; i<=m; i++ ) {
int x,y,z;
cin >> x >> y >> z;
if ( a[x][y]>z ) {
a[x][y] = a[y][x] = z;
}
}
dijkstra(1);
return 0;
}