### 堆优化 使用情况(n和m一个级别的时候)
```
#include<bits/stdc++.h>
#define PII pair<int,int>// first存距离,second存起点
using namespace std;
const int N = 5e5+10;
int h[N],e[N],w[N],ne[N],idx;//邻接表存图
int n,m,s;//节点数,边数,起点
int dist[N];//每个点到起点的距离
bool st[N];//记录每个点到起点的距离是否已经确定
void add(int a,int b,int c)
{
e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
//参考单链表的插入方式,在头部插入
}
void dijkstra()
{
memset(dist,0x3f,sizeof dist);//将所有节点设为无穷大
dist[s] = 0;//起点到自己的距离为0
priority_queue<PII,vector<PII>,greater<PII>> q;//建一个小根堆,堆头就是目前离起点最近的点,且复杂度客观
q.push({0,s});//将起点入堆
while(q.size())//队列不空时不断循环
{
auto t = q.top();//将队首取出
q.pop();//弹出队首
int ver = t.second;//记录队首的节点编号
if(st[ver]) continue;//如果已经确认过最短距离了就不用再更新了
st[ver]=true;//将状态设为已更新
for(int i = h[ver];i!=-1;i=ne[i])//遍历点ver 的所有出边
{
int j = e[i];//记录边i的终点j
if(dist[j]>dist[ver]+w[i])//如果距离更小则更新
{
dist[j] = dist[ver]+w[i];
q.push({dist[j],j});//将这个更新过的点入队,因为队列中存的是离起点近的点,如果没有被更新一定没有队列里的小
}
}
}
}
int main()
{
memset(h,-1,sizeof(h));//将邻接表头初始化
cin>>n>>m>>s;
while(m--)//读入每一条边
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
}
dijkstra();
for(int i = 1;i<=n;i++)
{
if(dist[i]==0x3f3f3f3f) cout<<(1<<31)-1<<" ";
else cout<<dist[i]<<" ";
}
return 0;
}
```
dijkstra(堆优化)算法代码+理解
最新推荐文章于 2024-08-17 01:33:11 发布