【2017.12.18】Dijkstra专题

先友情提示一下,作者很早就会这个算法了,只不过这么久以来没怎么写过博客。现在正在学习它的拓展,干脆就把这个算法相关的内容整个敲一遍吧!本章把迪杰斯特拉从基础到拓展全都说一遍咯。

下面是优先队列(堆)优化后的dij代码。

#include<queue>
#include<vector>
#define inf 0x3f3f3f
struct Edge{
	int to,dis; //to表示目标点,dis表示边的权值 
};

struct HeapNode{ //记录dij算法用到的优先队列中的节点
    int d,u;
    bool operator <(const HeapNode& rhs) const{
    	return d>rhs.d;
    }
};

struct Dijkstra{
	int n,m;
	vector<Edge> edges; //边列表 
	vector<int> G[maxn]; //每个节点的出边的编号,也可以手写邻接表(没开O2的话建议手写) 
	int d[maxn],p[maxn]; //d[i]表示起点s到i的最短距离,p[i]表示从s到i最短路中的上一条边 
    
    void init(int n){
    	this->n = n;
    	for(int i=0;i<n;i++) G[i].clear(); // 清空邻接表
		edges.clear(); //清空边表 
	}
	
	void Addedge(int from,int to,int dis){
		edges.push(back(Edge){to,dist});
		m=edges.size();
		G[from].push_back(m-1);
	}
	
	void dij(int s){ //求起点s到所有点的距离 
		priority_queue<Heapnode> q;
		for(int i=0;i<n;i++) d[i]=inf;
		d[s]=0;
		q.push((HeapNode){0,s});
		while(!q.empty()){
			Heapnode x=q.top(); q.pop();
			int u=x.u;
			if(d[i]!=inf) continue; //已经被确定过距离的点不再重复确定 
			for(int i=0;i<G[u].size();i++){
				Edge& e=edges[G[u][i]]; //引用符号(&)相当于在循环中用e代替了edges[G[u][i]],任何对e的调用和赋值都会转成edges[G[u][i]] 
				if(d[e.to]>d[u]+e.dis){ //新距离比历史距离更短,更新
d[e.to]d[u]+e.dis; p[e.to]=G[u][i]; q.push((HeapNode){d[e.to],e.to}); } } } } };
原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/8058932.html