1. 程式人生 > >堆(優先佇列)優化dijkstra(鄰接矩陣)

堆(優先佇列)優化dijkstra(鄰接矩陣)

上篇部落格大家學習了最短路的兩種基本演算法,忘了告訴大家,floyd可以完成有負權值的最短路,而dijkstra則不行。若要想要更優的進行負權值最短路,請期待我的SPFA詳解。

現在開始堆優化dijkstra的講解。

其實只要理解了dijkstra的本質,這也就不難了,就是把查詢最小dis值的過程用堆實現即可。具體程式碼如下:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>

using
namespace std; int n,num,tree[10000][10],map[1000][1000],book[1000],dis[1000],m,i,j,mini,u; void swap(int x,int y){//堆操作 int t; t=tree[x][1]; tree[x][1]=tree[y][1]; tree[y][1]=t; t=tree[x][2]; tree[x][2]=tree[y][2]; tree[y][2]=t; } void siftdown(int i){//堆操作 int t,flag=0; while (i*2
<=n&&flag==0){ t=i; if (tree[i][1]>tree[i*2][1]) t*=2; if (i*2+1<=n){ if (tree[t][1]>tree[i*2+1][1]){ t=i*2+1; } } if (i!=t){ swap(i,t); i=t; } else flag=1; } } void
build(){//堆操作 int i; for (i=trunc(n/2);i>=1;--i) siftdown(i); } int posh(){ int t; t=tree[1][1]; tree[1][1]=tree[n][1]; n--; siftdown(1); return t; } int main(){ scanf("%d%d",&num,&m); n=num; for (i=1;i<=n;++i) for (j=1;j<=n;++j){ i==j?map[i][j]=0:map[i][j]=21474836; } for (i=1;i<=m;++i){ int x,y,z; scanf("%d%d%d",&x,&y,&z); map[x][y]=z; map[y][x]=z; } for (i=1;i<=num;++i){ dis[i]=tree[i][1]=map[1][i]; tree[i][2]=i; book[i]=0; } build(); book[1]=1; mini=posh(); for (i=1;i<=num-1;++i){ u=tree[1][2];mini=posh();//堆代替for迴圈 book[u]=1; for (j=1;j<=num;++j){ if (dis[j]>dis[u]+map[u][j]){ dis[j]=map[u][j]+dis[u]; } } } printf("%d",dis[num]); }

下次,我將發表關於最小生成樹演算法的部落格,請大家繼續關注,靴靴。。。。