堆(优先队列)优化dijkstra(邻接矩阵)

上篇博客大家学习了最短路的两种基本算法,忘了告诉大家,floyd可以完成有负权值的最短路,而dijkstra则不行。若要想要更优的进行负权值最短路,请期待我的SPFA详解。

现在开始堆优化dijkstra的讲解。

其实只要理解了dijkstra的本质,这也就不难了,就是把查询最小dis值的过程用堆实现即可。具体代码如下:

#include 
#include 
#include 
#include 
#include 

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]);
}

下次,我将发表关于最小生成树算法的博客,请大家继续关注,靴靴。。。。

你可能感兴趣的:(图)