Dijkstra算法
适用范围
单源最短路
思路
核心思想:贪心.从第一个最短距离已经确定的点出发(起点),找到起点为最短距离确定的点的边,按边的权值从小到大通过这些边去更新这些边的终点(此过程可以用优先队列优化),从而不断确定点的最短距离,直到最后所有点的最短距离均确定.这里要说明一下,按原算法思路是无法跑负边的,因为存在负边的话已经确定最短距离的点可能会在以后的更新中距离变得更短.但以下代码优化之后有负边也可以跑,但是不能跑负环(指环中边权值之和为负数),因为存在负环的话最短路会不断更新.
复杂度:O(ElogV).
代码(已优化)
1 typedef pair<int,int> P;//first值是最短距离,second是点 2 struct edge{int to,cost;}; 3 int n,m;//n点,m边 4 vector<edge> es[MAX+1]; 5 int d[MAX+1]; 6 7 void dijkstra(int s) 8 { 9 priority_queue<P,vector<P>,greater<P> > que; 10 fill(d+1,d+n+1,INF); 11 d[s]=0; 12 que.push(P(0,s)); 13 while(que.size()) 14 { 15 P p=que.top();que.pop(); 16 int v=p.second; 17 if(d[v]<p.first) continue; 18 for(int i=0;i<es[v].size();i++) 19 { 20 edge e=es[v][i]; 21 if(d[e.to]>d[v]+e.cost) 22 { 23 d[e.to]=d[v]+e.cost; 24 que.push(P(d[e.to],e.to)); 25 } 26 } 27 } 28 }