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;
}
查看3道真题和解析
美团成长空间 2791人发布