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;
}


全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务