今天百度學習了一下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 205struct 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 100 3 300 4 1001 2 502 4 103 4 603 2 20outpu:0 10 50 30 60*/