acwing850Dijkstra求最短路II,堆优化
堆优化,主要用于m~n数量级较近,换句话说m~n2数量级较远
时间复杂度o(mlogn),相当于遍历了每条边,如果插入用logn
伪代码
优先队列--小根堆<距离,点号> q 起点入队,最小起点距离dist[起点]=0,st[起点]记录 while(非空){ 目前最小点top=堆顶 出队 点var=top的点号, distance=top的距离 if (已经存入)跳过循环 else 标记存入var for 遍历var邻边 o(m) 用var做中转更新每一未存点距离 如果更小放入队列 o(logn) }代码
#include <bits/stdc++.h> using namespace std; typedef pair<int ,int> PII; const int N=100005; int e[N],ne[N],h[N],w[N],idx;//邻接表记录了每点邻边,e【】记录邻点,w【】记录这条边权,即距离 int n,m,a,b,c; int dist[N]; bool st[N]; priority_queue<PII,vector<PII>,greater<PII>> q;//priority_queue<PII> q; void add(int a,int b,int c){ e[idx]=b, ne[idx]=h[a], w[idx]=c, h[a]=idx++; } int dijkstra(){ memset(dist,0x3f,sizeof dist); q.push({0,1}); // st[1]=true; dist[1]=0; while(q.size()){ PII top=q.top(); q.pop();//!!!!!!!!!!!! int var=top.second, distance=top.first; if(st[var]) continue; st[var]=true;//!!!!!!!!!!! for(int i=h[var];i!=-1;i=ne[i]){ int pt=e[i]; if(dist[pt]>distance+w[i]){//if(dist[pt]>distance+w[i]&&!st[pt]){ q.push({distance+w[i],pt}); dist[pt]=distance+w[i]; // st[pt]=true; } } } if(dist[n]==0x3f3f3f3f) return -1; return dist[n]; } int main() { cin>>n>>m; memset(h,-1,sizeof(h)); for(int i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); add(a,b,c); } cout<<dijkstra()<<endl; return 0; }