dijstra算法堆优化
作者:
Qjwwww
,
2022-04-08 09:04:14
,
所有人可见
,
阅读 265
//dijstra算法----堆优化版本O(ElogE) E:边的数量
//基于优先队列的堆优化算法
#include<bits/stdc++.h>
using namespace std;
const int N = 150010;
int h[N],to[N],nxt[N],w[N];
int vis[N];//记录有没有通过结点i进行过松弛操作,而不是有没有求出该点的最短路径
int n,m;
int cnt;
int dist[N];//存储当前到结点i的最短路径
#define inf 0x7ffffff
void addedge(int a,int b,int val)
{
nxt[++cnt] = h[a];
h[a] = cnt;
to[cnt] = b;
w[cnt] = val;
}
//node是优先队列中的元素
struct node{
int id,dis;
bool operator <(const node &a)const {return a.dis<dis;}
//看不到直接、背下来
//优先队列缺省是大顶堆,即数值大的优先级更大
//因为要进行松弛操作,所以重载<,让其变为小顶堆,即值小的优先级更高
};
void dijstra()
{
priority_queue<node> q;
q.push(node{1,0});//直接默认构造函数
for(int i=1;i<=n;i++) dist[i] = inf;
//初始dist均为无穷大
dist[1] = 0;
//由题意知,是从结点1出发,所以dist[1] = 0
while(!q.empty())
{
node a = q.top();
//取出优先队列中优先级最大的元素,即距离已知最短的点
//然后再基于该元素进行松弛操作----核心
q.pop();
int now = a.id;
if(vis[now]) continue;//如果已经经过了松弛操作,则continue
vis[now] = 1;
for(int i=h[now];i;i=nxt[i])
{
int j = to[i];
//松弛操作!!
if(dist[j]>dist[now]+w[i])
{
dist[j] = dist[now] + w[i];
q.push(node{j,dist[j]});
}
}
}
}
int main()
{
cin>>n>>m;
int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
//对于链式前向星而言,无需特殊处理重边、自环等情况
//直接加进去即可
}
dijstra();
if(dist[n]==inf) cout<<"-1";
else cout<<dist[n];
return 0;
}