前景提要:最短路:dijkstra堆优化_物联网土猫的博客-优快云博客
上次我们这里采用了直接开小根堆的priority_queue,但是很多家人可能连基本的queue都不会写,要是直接跳这么多感觉不是很好,所以这里我们给大家提供上一次博客中提到的另一种方法;
也就是把权值赋为负值以此实现内部排序的小根堆;
这里和上次的方法差不多,只是变成了小根堆,需要你存入权值的时候存入负值即可,遍历也和上次一样,重点是,只适用于没有重边的的情况,至于为何需要大家自行思考;
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=100010;
priority_queue<pair<int,int>> q;
int h[N],e[N],ne[N],idx,eng[N];//单链表模板背上即可,eng存储权重
bool st[N];//存是否已被循环过
int ans[N];//存答案
int n,m;
void add(int a,int b,int c)
{
e[idx]=b,ne[idx]=h[a],eng[idx]=c,h[a]=idx++;
}
int dijkstra()
{
memset(h,-1,sizeof(h));
memset(st,0,sizeof(st));
memset(ans,0x3f,sizeof(ans));
ans[1]=0;
q.push(make_pair(0,1));
while(q.size()!=0)
{
int dist=-q.top().first,a=q.top().second;// 这里不开dist也可以,有了a的话,ans[a]其实就是dist
q.pop();
if(st[a]) continue;//如果已经是true的话说明已经是最短,不用更改了
//其实这里很多同学会迷惑啊,说明明这个点的做短路已经更改了,按理说
//他的出边也应该更改的,为啥直接跳过了呢?
//这里博主一句话讲不清楚,大家多画个图多试几种情况就可以知道了
st[a]=true;
for(int i=h[a];i!=-1;i=ne[i])
{
if(ans[e[i]]>dist+eng[i])//更新出边
{
ans[e[i]]=dist+eng[i];
q.push(make_pair(-e[i],i));//只有更新了出边的点才需要加入进行更新
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);//这里没有考虑重边与自环,如果有的话大家就不能使用单链表来存储,因为重边会造成错误
// if(std(a,b)==0)
// {
// add(a,b,c);
// std[a][b]=1;
// }
// else
// if(an[a][b]>c)
// add(a,b,c);//大家思考一下,这样写来消除重边的写法为何是错误的?
}
}