一般的dijkstra算法利用贪心的思想,每次找出最短边,然后优化到该点的的距离,我们还采用贪心思路,但在寻找最短边进行优化,之前是双重for循环,现在我们用优先队列来实现。
代码解释:
//样例程序采用边表储存。
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
 
int head[100000]={0},next[200000]={0},aa[200000]={0},size,s,tt,m,n;
struct bb
  {
  	int x,y;
  }a[100000];//记录点的横纵坐标。
double val[100000],dis[100000]={0}; 
 void add(int h,int t,double c)//建立边表。
    {
    	size++;//对边进行重编号。
    	next[size]=head[h];
    	head[h]=size;
    	aa[size]=t;
    	val[size]=c;
	}
	
 void init()
   {
   	  scanf("%d",&n); 
   	  for (int i=0;i<n;i++)
   	      { 
   	      	 int u,v;
   	      	 double c;
			 scanf("%d%d",&u,&v); //读入有边的两点。
			 c=sqrt((a[u-1].x-a[v-1].x)*(a[u-1].x-a[v-1].x)+(a[u-1].y-a[v-1].y)*(a[u-1].y-a[v-1].y));//用数学公式求出两点间距离。
   	      	 add(u,v,c);//建立由u到v的边,权值为c;
   	      	 add(v,u,c);//若图为有向图,则省略该语句。
			 }
	  scanf("%d%d",&s,&tt); //读入所求的由s到tt的距离。目标。
   }   
   
 void initint()//存下点的坐标。
    {
    	scanf("%d",&m);
    for (int i=0;i<m;i++)	
    	scanf("%d%d",&a[i].x,&a[i].y); 
	}
   
struct ss//定义优先队列的自定义结构体。
   {
   	 int x;
   	 double y;
   	 ss(){}//定义构造函数。
   	 ss(int xx,double yy)//重载该函数。
   	   {
   	   	  x=xx;
   	   	  y=yy;
		  }
   	 bool operator<(const ss& b)const//重载<运算符(因为我们要找最小值,而优先队列默认为大根堆)。
   	   {
   	   	  return y>b.y;
		  }
   };
   
 void dij()//dijkstra算法
   {
   	 priority_queue<ss>que;//定义优先队列,不懂看“C++之路启航——标准模板库(queue)”
   	 que.push(ss(s,0));//把起点压入队列中。
   	 for (int i=0;i<=m;i++)//
   	    dis[i]=100000000;
   	 dis[s]=0;// 初始操作。
   	 while (!que.empty())
   	      {
   	      	 ss op=que.top();//取出最小值。op.x为点的编号,op.y为从起点到该点的距离。
   	      	 que.pop();
   	      	 if (op.y>dis[op.x]) continue;//一步优化。
   	      	 for (int i=head[op.x];i!=0;i=next[i]) //遍历与该点相连的边。
   	      	      {
   	      	      	   int j=aa[i];
   	      	      	   if (dis[j]>dis[op.x]+val[i])//找到能够更新的,并且压入队列中。
   	      	      	       {
   	      	      	       	    dis[j]=dis[op.x]+val[i];
   	      	      	       	     que.push(ss(j,dis[j]));
								  }
					   }
			 }
   	printf("%.2f",dis[tt]);//输出;
   	return;
   }
 
int main()
   {
   	initint();
   	init();
   	dij();
   	return 0;
	} 
C++之路进阶——优先队列优化最短路径算法(dijkstra)
原文:http://www.cnblogs.com/grhyxzc/p/5079583.html