[算法模板]Dijkstra算法笔记

Dijkstra

本篇文章属于个人笔记,不适合详细了解和解读此算法 ,不过代码,代码已详细注释可以学习参考。

简介

实现单源点最短路

  • 此算法可以得出单源点到达其他节点的最短路径和权值

思路

  • 前置: 距离数组,前置数组

  • 初始化

    • 图全部初始化为无穷大

    • 输入 顶点 边

    • 输入源点

  • 寻找最短路

    1. 将源点添加到S数组【视为当前最优】

    2. 将源点的距离设置为 0

    3. 开始寻找dist(距离)中最小的,并得到距离最小的节点

    4. 将找到的添加到S数组中

    5. 从 当前得到的最小节点开始拓展最小节点可以到达的节点 和当前源节点能到达的节点 进行距离比较

      • 如果从最小节点到达最优
        • 到达的节点 dist距离更新,前置更改为 最小节点
      • 其他情况保持原状
    6. 返回 三步骤,直到全部 节点标记到S数组

代码实现[详细注解]

#include <iostream>
#include <cstring>
using namespace std;
const int N = 999999;// 无限大
typedef struct{
   int vex[100]; // 顶点
   int edge[100][100]; //边
   int vexnum; // 顶点总数
   int edgenum; // 边总数

}maps;
/*
5 
8
1 2 3 4 5
  1 2 2
  1 3 5
  2 3 2
  2 4 6
  3 4 7
  3 5 1
  4 3 2
  4 5 4
  1
  
*/
int dist[100]; // 距离
int pervious[100]; // 上一个
bool flag[100]; // 是否是s集合

int  find_vex(maps g,int u){
    for (int i = 1; i <= g.vexnum; i++)
    {
        if(g.vex[i] == u) return i;
    }
    return -1;
    
}

void Create_map(maps &g){
   cout << "请输入节点大小:";
   cin >> g.vexnum;
   cout << "请输入边的大小:";
   cin >> g.edgenum;
   /*  初始化图  */
   for (int i = 1; i <= g.vexnum; i++)
   {
     for(int j = 1; j <= g.vexnum;j++){
       g.edge[i][j] = N;
     }
   }
   cout << "图初始化完成" << endl;
   /* 初始化结束 */

  /*   输入顶点   */
   int u,v,w; // 源点,终点,权值
   cout << "请输入顶点:";
   for (int i = 1; i <= g.vexnum; i++)
   {
      cin >> g.vex[i];
   }
  /*  输入顶点结束  */
   cout <<"顶点输入完毕" << endl;
  /*  输入边   */
  for (int i = 1; i <= g.edgenum; i++)
  {
     cin >> u >> v >> w;
     u = find_vex(g,u);
     v = find_vex(g,v);
    
     if(u!=-1 && v!=-1){ // 如果找到了
         g.edge[u][v] = w;
     }else{
        cout << "XXXXX.XXXXXX输入错误!!" << endl;
        i--;
     }

     
  }
  /*  输入边结束  */

  cout << "=-输入完毕-= 初始化完成";

}

void dijkstra(maps g,int u ){
    /*  最短路  */

    /*Step1  初始化 dist and pervious  */
    for (int i = 1; i <= g.vexnum; i++){
        if(g.edge[u][i]!=N){
            /*  如果可到达  */
            dist[i] = g.edge[u][i];
            pervious[i] = u;
            
        }else{
            /*  如果不可到达  */
            dist[i] = N;
            pervious[i] = -1;
        }
    }

    /*Step2 初始化起点  */
      dist[u] = 0;
      flag[u] = true; 

    /*Step3 遍历*/
    for (int i = 1; i <= g.vexnum; i++)
    {
        int temp_min = N; // 最小距离
        int temp_min_node = u; // 最小节点
        /*    寻找最小节点   */
        for (int j = 1; j <= g.vexnum; j++){
             if(!flag[j] && dist[j] < temp_min){
                temp_min = dist[j];
                temp_min_node =  j;
             }
        }
        /*  寻找最小节点结束  */


        if (temp_min_node == u) return; // 没找到
        flag[temp_min_node] = true; // 加入优先集合

        /*  遍历刚加入优先集合可到达的节点和原先的节点进行距离比较 */
        for (int j = 1; j <= g.vexnum; j++){
            if(!flag[j] && g.edge[temp_min_node][j]!=N){
                if(dist[j] > (dist[temp_min_node] + g.edge[temp_min_node][j])){
                    dist[j] = dist[temp_min_node]+g.edge[temp_min_node][j];
                    pervious[j] = temp_min_node;
                }
            }
            
        }
        

        
    
        

        
    }
    


    
      
}
int main(){
    maps G;
    memset(flag,false,sizeof(flag));
    memset(dist,-1,sizeof(dist)); // 初始化距离
    memset(pervious,-1,sizeof(pervious));
    Create_map(G);
    cout << "请输入开始的源点:";
    int u;
    cin >> u;
    u = find_vex(G,u);
    dijkstra(G,u);
    cout <<"Start:" << u << endl;
    for (int i = 1; i <= G.vexnum; i++)
    {
        int v = find_vex(G,i);
        cout << u << " to " << i << "  "<<dist[v] << endl;
    }
    
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值