今天百度学习了一下stl multiset,无意间发现了这么一篇文章,正权边的最短路问题可以用dijkstra算法来解决,而优化dijkstra算法可以用heap。这里我们来看如何用multiset实现dijkstra+heap http://hi.baidu.com/vaeibomz/blog/item/326f2e3af02789ee828b1386.html
以下是代码:
#include<iostream> #include<cmath> #include<algorithm> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<set> using namespace std; #define N 205 struct Adj { int parent,child,brother,w; } adj[N]; int tol,head[N],end; int d[N]; void add(int from,int to,int val) { adj[tol].parent=from; adj[tol].child=to; adj[tol].brother=head[from]; adj[tol].w=val; head[from]=tol++; } struct rec { int x,y; }; struct cmp { bool operator()(const rec&a,const rec&b) { return (a.x<b.x)||(a.x==b.x&&a.y<b.y); } }; multiset<rec,cmp> h; void dijkstra_heap()//从0开始 { //初始化 d[0]=0;//源点是0 rec a; a.x=0;//第一关键字x表示距离 a.y=0;//第二关键字y表示点的编号 h.insert(a);//将a插入序列中 // while(!h.empty())//h集合中的元素是否为空 { __typeof(h.begin()) c=h.begin(); rec t=(*c);//取最小值 h.erase(c);//将最小值删去 for(int i=head[t.y]; i!=end; i=adj[i].brother) { int j=adj[i].child; rec a;//建立一个结构类变量a if(d[j]==-1)//d[j]==-1表示j还没有被访问 { d[j]=t.x+adj[i].w;//w[i]表示边i的边权 a.x=d[j]; a.y=j;//将j的相关信息保存在rec类型a中 h.insert(a); } else if(d[j]>t.x+adj[i].w)//最短路算法的松弛操作 { a.x=d[j]; a.y=j;//将j在序列中的信息存储到a中 c=h.upper_bound(a);//找到序列h中a之后的元素的地址 c--;//地址减一就是a所在的地址 h.erase(c);//删掉a a.x=t.x+adj[i].w; d[j]=a.x;//更新最短路的值 h.insert(a);//插入 } } } } int main() { freopen("in.txt","r",stdin); tol=0; end=-1; memset(head,end,sizeof(head)); memset(d,-1,sizeof(d)); int n=7,a,b,c; for(int i=1; i<=n; i++) { scanf("%d %d %d",&a,&b,&c); add(a,b,c); add(b,a,c); } dijkstra_heap(); for(int i=0; i<5; i++) cout<<d[i]<<" "; cout<<endl; return 0; } /* input: 0 1 10 0 3 30 0 4 100 1 2 50 2 4 10 3 4 60 3 2 20 outpu: 0 10 50 30 60 */