Algorithm 最短路径之 Dijkstra的优化

本文深入探讨了Dijkstra算法的原理与应用,通过代码实例展示了如何使用优先队列和静态邻接表来解决最短路径问题。文章详细介绍了算法的初始化步骤与核心遍历过程,同时提供了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dijkstra算法利用了优先队列,也用到了静态邻接表。主要也是有两部分组成。一: 当然是初始化。将dist和pre分别赋值,然后输入各条边的信息,存储在静态邻接表中 。二: 中Dijkstra中 将Q.push(temp) .然后利用for(i =pre[nod] ; i != -1 ;i = edge[i].next)将每条与temp有关联的边进行遍历。能松弛的点push到Q中。详细看下面的代码。

<span style="font-size:18px;">#include
#include
#include
#include
#include

using namespace std ;

#define MAXN 1000
#define INF 1000000

int map[MAXN][MAXN] ;
int visit[MAXN] ;
int pre[MAXN] ;
int dist[MAXN] ;
int path[MAXN] ;
int top ;

struct node{
    
    int p ;
    int value ;
    
    friend bool operator < (node a , node b ){
        
        return a.value > b.value ;
    }
};

priority_queue Q ;

struct Edge
{
    int to ;
    int w ;
    int next ;
    
}edge[MAXN*MAXN];


void addedge(int x ,int y , int w )
{
    edge[top].to = y ;
    edge[top].w = w ;
    edge[top].next = pre[x] ;
    pre[x] = top ;
    top++ ;
}

void init (int n, int m)
{
    int i , j ;
    top = 1 ;
    
    memset(pre , -1 ,sizeof(pre)) ;
    for(i = 1 ;i <= n ; i++)
        dist[i] = INF ;
    dist[1] = 0 ;
    for(i = 1 ;i <= n ; i++){
        for(j = 1 ;j <= n ; j++){
            map[i][j] = INF ;
            
        }
    }
    
    for(i = 1 ;i <= m ; i++){
        int x ,y , w ;
        scanf("%d%d%d" ,&x ,&y , &w) ;
        if(map[x][y] < w) continue ;
        addedge(x,y,w) ;
        addedge(y,x,w) ;
        map[x][y] = map[y][x] = w ;
        
    }        
}



void Dijkstra (int  n )
{
    memset(visit , 0 ,sizeof(visit)) ;
    node temp ;
    
    while(!Q.empty()) Q.pop() ;
    
    temp.p = 1 ;
    temp.value = 0 ;
    Q.push(temp) ;
    
    path[1] = -1 ;
    
    while(!Q.empty())
    {
        temp = Q.top() ;
        Q.pop() ;
        
        int nod = temp.p ;
        int w = temp.value ;
        if(visit[nod]) continue ;
        visit[nod] = 1 ;
        int i ;
        for(i = pre[nod] ; i != -1 ;i = edge[i].next ){
            
            
            int    t = edge[i].to ;
            if(visit[t]) continue ;
            
            int v = edge[i].w ;
            
            if(dist[nod] + v < dist[t])
            {
                dist[t] = dist[nod] + v ;
                
                path[t] = nod ;
                
                node next ;
                next.p = t ;
                next.value = dist[t] ;
                Q.push(next) ;
            }
        }
        
    }
    
}


int main()
{
    int m , n ;
    int i , j ;
    int ans[MAXN] ;
    while(scanf("%d%d" ,&n, &m )!=EOF ){
        if(n == 0 && m == 0) break ;
        init(n ,m) ;
        
        Dijkstra(n) ;
        
        printf("%d\n",dist[n]) ;
        
        int t = 0 ;
        for(i = n ; i != -1 ; i = path[i]){
            ans[t++] = i ;
        }
        for(i = t-1 ; i >= 0 ; i--){
            printf("%d ",ans[i]) ;
        }
        printf("\n") ;
        
        
    }
    
    return 0;
}</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值