关于dijkstra求最短路(模板)

嗯....

 

dijkstra是求最短路的一种算法(废话,思维含量较低,

 

并且时间复杂度较为稳定,为O(n^2),

 

但是注意:!!!!         不能处理边权为负的情况(但SPFA可以处理,今后会讲)

 

借一个何大佬的图,因为会在代码中提到红、绿、空三种颜色,以及小v,

 

通过图会比较清晰一些:

 

思路大约明白了下面就呈上带批注模板代码:

 1 #include <cstdio>//dijkstra求最短路
 2 #include <cstring>
 3 #include <algorithm> 
 4 using namespace std;
 5 const int maxn=10005;
 6 int g[maxn][maxn], n, m;//g数组用来存图 
 7 int dis[maxn], status[maxn];//dis数组中存储的是从起点到第i个点的最短路长度 
 8 
 9 
10 /*status//(状态)用来存点的类型,1.已经求出最短路的点(把它想成红色,用2来表示) 
11 2.是从已经求出最短路的点向外延伸一次就可找到的点(把它想成绿色,用1来表示)
12 3.其余还没有访问的,仍没有色(用0来表示)*/ 
13 
14 
15 //注意每一种算法都要新开一个函数,使代码简单易懂 
16 void dijkstra(int start_point) {//dijkstra 最短路写法: 
17     memset(dis, 0x3f, sizeof(dis));//将dis数组中的每一个元素都设为正无穷,
18     //因为后面要用它与更小的最短路进行比较,所以它为最大,且定义为正无穷 
19     dis[start_point] = 0;//确定边界,起点的最短路一定为0 
20     status[start_point] = 1;//起点已求出最短路,首先标记为绿色,进行分析 
21     for (int ti = 0; ti < n; ++ti) //枚举n次 
22     {
23         int vertex_to_pick = -1;//将小V初始化为-1(小V即为要找的点) 
24         for (int i = 1; i <= n; ++i) //再次进行枚举 
25         {
26             if (status[i] == 1) //如果i点为绿色 
27             { 
28                 if (vertex_to_pick == -1 || dis[i] < dis[vertex_to_pick])
29                 //如果v还没有被更新或者说是找到一个点i比点v到出发点的距离更近,则也进行更新 
30                  {
31                     vertex_to_pick = i;//进行更新 
32                 }
33             }
34         }
35         if (vertex_to_pick == -1) {
36             break;//如果找不到下一个点,则退出 
37         }
38         status[vertex_to_pick] = 2;//将已经更新好的最近的v添加到red集合 
39         for (int i = 1; i <= n; ++i) 
40         //从找到的v点进行更新dis数组
41         {
42             if (status[i] == 0 || status[i] == 1) //如果i点还没有添加到red集合 
43             {
44                 if (g[vertex_to_pick][i] != -1)// 并且满足从小v这个点到i点有距离 
45                 {
46                     status[i] = 1;//再次将i点加入绿色集合,进行循环,找到所有相邻点 
47                     dis[i] = min(dis[i], dis[vertex_to_pick] + g[vertex_to_pick][i]);//更新i点的最短路 
48                 }
49             }
50         }
51     }
52 }
53 
54 
55 
56 int main() {
57     //主函数进行输入、调用、输出 
58     memset(g, -1, sizeof(g));
59     scanf("%d%d", &n, &m);
60     for (int i = 0; i < m; ++i) {
61         int u, v, w;
62         scanf("%d%d%d", &u, &v, &w);
63         g[u][v] = g[v][u] = w;
64     }
65     dijkstra(1);
66     printf("%d",dis[n]);
67     return 0;
68 }

 

多背几遍应该能明白,   反正一直除了更新就是更新.....

转载于:https://www.cnblogs.com/New-ljx/p/10389341.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值