利用优先队列实现的dijkstra算法

            dijkstra算法是典型的贪心算法,但如果没有好的数据结构支持的话,O(v^2)的效率还是让人有点不满意,不过如果利用优先队列的话就能轻松的实现O(ElogV+VlogV),对       于稀疏图来说,这是很令人满意的!废话不多说,下面就是我的C++代码:

#include<iostream>
#include<queue>
#include<vector>
#include<stdio.h>
using namespace std;
#define INFINITY 1000000000
class graph
{
public:
	struct weight{
		int num;
		int w;
		weight(int n,int ww=0):num(n),w(ww){}
	};
	struct vdist{
	 int num;
	 int dist;
	 vdist(int n=0,int d=INFINITY):num(n),dist(d){}
    friend 	bool operator <(const vdist &v1,const vdist &v2)
		{
		   return	v1.dist>v2.dist;
		}

	};
	struct vertex
	{
	public:
		int num;         //点在图中的编号
		int dist;        //离待测点的距离
		vector<weight >L;      //与此顶点相关的边
		bool known;      //是否已经确定为最短路径
		int path    ;  //前驱元
		vertex(int n=0,int dist=INFINITY,bool k=false):num(n),dist(dist),known(k){}
		void merge(int x,int y)
		{
		   weight p(x,y);
		   L.push_back(p);

		}

	};
	vector<vertex>v;
	int N;
	public:
		graph(int x):N(x)
		{
			for(int i=0;i<N;i++)
                  {
                    vertex tmp(i);
                    v.push_back(tmp);
                    }
        }

		void merge(int x,int y,int weight)
		{
				v[x].merge(y,weight);

		}
		void dijkstra(int s)
		{
			priority_queue<vdist> Q;
			  v[s].dist=0;
				v[s].path=s;
			for(int i=0;i<N;i++)
				{
				  vdist tmp(v[i].num,v[i].dist);
				  Q.push(tmp);
				  }
			int count=0;
			for(;count<N;count++)
			{
				vdist v1=Q.top();
				Q.pop();
                int Num=v1.num;
                 while(v[Num].known)
				{

					v1=Q.top();
					Q.pop();
					Num=v1.num;
				}
				v[Num].known=true;cout<<v[Num].dist<<endl;
				int siz=v[Num].L.size();
                for( int i=0;i<siz;i++)
					{
						 int Num1=v[Num].L[i].num;

						if(!v[Num1].known)
							if(v[Num].dist+v[Num].L[i].w<v[Num1].dist)
							{
								v[Num1].dist=v[Num].dist+v[Num].L[i].w;
								v[Num1].path=Num;
								vdist tmp(v[Num1].num,v[Num1].dist);
								Q.push(tmp);
							}
					}

				}
		}

 int sum_dist()
 {
     int  sum=0;
     for(int i=1;i<N;i++)
     sum+=v[i].dist;
     return sum;
 }
 int ndist()
 {
   return v[N-1].dist;
 }
};
int main()
{
    int n,m,T;
while(cin>>T)
   while( T--)
   {
     cin>>n>>m;

    graph G1(n);

      int u,v,w;
      while(m--)
      {
        cin>>u>>v>>w;
        G1.merge(u-1,v-1,w);
        }
        G1.dijkstra(0);
      cout<<G1.sum_dist()<<endl;
}
 
	return 0;
}

  这程序有点难看,因为中间改了很多,不过在HDU acm 里是能运行通过的,哈哈!这次的程序因为一点小错误让我做了好久阿,真是令人难忘的体验呢!

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/alop_daoyan/article/details/21296101
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞