单源最短路径——Dijkstra算法

本文详细介绍迪杰斯特拉算法的思想及其C++实现过程。该算法适用于带权有向图,能够有效地找出从源点到图中其它各点的最短路径。通过不断更新顶点的最短路径长度,并维护两个顶点集合来保证算法效率。

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

算法描述

1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。

接下来以例子说明:
这里写图片描述

C++代码实现

#include<bits/stdc++.h> 
//#include<algorithm>
using namespace std;

const int maxn=50;
const int INF=1000;
int G[maxn][maxn];
int vsit[maxn];
int cost[maxn];
int path[maxn];
int sum;

void print_path(int v){
    if(v==path[v])  {
        cout<<1;
        return; 
    }
    sum+=G[v][path[v]];
    print_path(path[v]);
    cout<<"->"<<v;
}

void Dijkstra(int v,int n){
    vsit[v]=1;
    for(int i=1;i<n;i++){
        path[i]=v;
        cost[i]=G[v][i];
        if(G[v][i]<0){
            cost[i]=INF;
            path[i]=0;
        }   
    }
    path[v]=v;
    int k=v,q;
    for(int j=1;j<n-1;j++){
        int min=INF;
        for(int i=1;i<n;i++){
            if(!vsit[i]&&G[k][i]>0&&cost[i]<min){
                min=cost[i];
                q=i;
            }
        }
        vsit[q]=1;
        k=q;
        for(int i=1;i<n;i++){
            if(!vsit[i]&&G[k][i]>0&&G[k][i]+cost[k]<cost[i]){
                cost[i]=G[k][i]+cost[k];
                path[i]=k;
            }
        }
    }
}
int main(){
    memset(G,-1,sizeof(G));
    int n=7;    
    G[1][6]=14;G[1][2]=7;G[1][3]=9;
    G[2][3]=10;G[2][4]=15;G[2][1]=7;
    G[3][1]=9;G[3][2]=10;G[3][6]=2;G[3][4]=11;
    G[4][3]=11;G[4][2]=15;G[4][5]=6;
    G[5][4]=6;G[5][6]=9;
    G[6][5]=9;G[6][3]=2;G[6][1]=14;


    memset(vsit,0,sizeof(vsit));
    Dijkstra(1,n);
    for(int i=1;i<n;i++){
        sum =0;
        print_path(i);
        cout<<" sum="<<sum<<endl;   
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值