利用優先隊列實現的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 裏是能運行通過的,哈哈!這次的程序因爲一點小錯誤讓我做了好久阿,真是令人難忘的體驗呢!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章