您的位置:首页 > 其它

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

2014-03-15 20:38 417 查看
            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 里是能运行通过的,哈哈!这次的程序因为一点小错误让我做了好久阿,真是令人难忘的体验呢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息