• 最短路算法 —— Dijkstra算法


    用途:

    解决单源最短路径问题(已固定一个起点,求它到其他所有点的最短路问题)

    算法核心(广搜):

    (1)确定的与起点相邻的点的最短距离,再根据已确定最短距离的点更新其他与之相邻的点的最短距离。

    (2)之后的更新不需要再关心最短距离已确定的点

    三种实现模板:

    一、矩阵朴素版

    二、vector简单版

    三、静态邻接表有点复杂版

    复制代码
      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <deque>
      5 #include <cstdio>
      6 #include <vector>
      7 #include <queue>
      8 #include <cmath>
      9 #define INF 0x3f3f3f3f
     10 using namespace std;
     11 
     12 //邻接矩阵
     13 
     14 const int MAXN = 110;
     15 int dis[MAXN];
     16 int e[MAXN][MAXN];
     17 bool vis[MAXN];
     18 int N, M;
     19 
     20 void dij()
     21 {
     22     int p, mis;
     23     for(int i = 1; i <= N; i++)
     24         dis[i] = e[1][i];
     25 
     26 
     27     vis[1] = true;
     28     dis[1] = 0;
     29     for(int i = 1; i < N; i++)
     30     {
     31         mis = INF;
     32         for(int j = 1; j <= N; j++)
     33         {
     34             if(!vis[j] && dis[j] < mis)
     35             {
     36                 mis = dis[j];
     37                 p = j;
     38             }
     39         }
     40         vis[p] = true;
     41 
     42         for(int k = 1; k <= N; k++)
     43         {
     44             if(dis[k] > dis[p] + e[p][k] && !vis[k])
     45                 dis[k] = dis[p] + e[p][k];
     46         }
     47     }
     48 }
     49 
     50 void init()
     51 {
     52     for(int i  = 1; i <= N; i++)
     53         for(int j = 1; j <= N; j++)
     54             if(i == j) e[i][j] = 0;
     55             else e[i][j] = INF;
     56     memset(vis, false, sizeof(vis));
     57 }
     58 int main()
     59 {
     60     int a, b, c;
     61     while(~scanf("%d%d", &N, &M))
     62     {
     63         if(N == 0 && M == 0) break;
     64         init();
     65         while(M--)
     66         {
     67             scanf("%d%d%d", &a, &b, &c);
     68             e[a][b] = c;
     69             e[b][a] = c;
     70         }
     71 
     72         dij();
     73         printf("%d
    ", dis[N]);
     74     }
     75 
     76     return 0;
     77 }
     78 
     79 
     80 
     81 //vector 动态邻接表 + 优先队列
     82 
     83 const int MAXN = 1e3 + 50;
     84 struct edge
     85 {
     86     int to, cost;
     87     edge(int vo = 0, int vt = 0):
     88         to(vo),cost(vt){}
     89 };
     90 
     91 vector<edge>G[MAXN];
     92 typedef pair<int, int>P;
     93 int dis[MAXN];
     94 int N, M;
     95 
     96 void init()
     97 {
     98     for(int i = 1; i <= N; i++)
     99     {
    100         G[i].clear();
    101         dis[i] = INF;
    102     }
    103 
    104 }
    105 void Dijkstra(int s)
    106 {
    107     int u, v;
    108     priority_queue<P, vector<P>, greater<P> > que;
    109     que.push(P(0, s));
    110     dis[s] = 0;
    111 
    112     while(!que.empty())
    113     {
    114         P p = que.top(); que.pop();
    115 
    116         int u = p.second;
    117         if(dis[u] < p.first) continue;
    118 
    119         for(int i = 0; i < G[u].size(); i++)
    120         {
    121             edge v = G[u][i];
    122             if(dis[v.to] > dis[u] + v.cost)
    123             {
    124                 dis[v.to] = dis[u] + v.cost;
    125                 que.push(P(dis[v.to], v.to));
    126             }
    127         }
    128     }
    129 }
    130 
    131 int main()
    132 {
    133     int u, v, c;
    134     scanf("%d%d", &N, &M);
    135     init();
    136     while(M--)
    137     {
    138         scanf("%d%d", &u, &v, &c);
    139         G[u].push_back(edge(v, c));
    140         //G[v].push(edge(u, c));  建无向图
    141     }
    142 
    143     //see see
    144     /*
    145     for(int i = 1; i <= N; i++)
    146     {
    147         for(int j = 0; j < G[i].size(); j++)
    148             printf("%d ", G[i][j].to);
    149         puts("");
    150     }
    151     */
    152 
    153     Dijkstra(1);
    154     for(int i = 1; i <= N; i++)
    155         printf("%d ", dis[i]);
    156     puts("");
    157 
    158     return 0;
    159 }
    160 
    161 
    162 
    163 
    164 ///静态邻接表 + 优先队列优化
    165 
    166 const int MAXN = 1e3 + 50;
    167 typedef pair<int, int> HeapNode;
    168 struct edge
    169 {
    170     int v, nxt, w;
    171 }G[MAXN*100];
    172 int head[MAXN], dis[MAXN];
    173 int N, M, cnt;
    174 
    175 inline void init()
    176 {
    177     for(int i = 0; i <= N; i++)
    178         head[i] = -1, dis[i] = INF;
    179     cnt = 0;
    180 }
    181 
    182 inline void add(int from, int to, int we)
    183 {
    184     G[cnt].w = we;
    185     G[cnt].v = to;
    186     G[cnt].nxt = head[from];
    187     head[from] = cnt++;
    188 }
    189 
    190 void dij()
    191 {
    192     priority_queue<HeapNode, vector<HeapNode>, greater<HeapNode> > heap;
    193     dis[1] = 0;
    194     heap.push(make_pair(0, 1));
    195     while(!heap.empty())
    196     {
    197         pair<int, int>T = heap.top();
    198         heap.pop();
    199 
    200         if(T.first != dis[T.second]) continue;
    201 
    202         for(int i = head[T.second]; i != -1; i = G[i].nxt)
    203         {
    204             int v = G[i].v;
    205             if(dis[v] > dis[T.second] + G[i].w)
    206             {
    207                 dis[v] = dis[T.second] + G[i].w;
    208                 heap.push(make_pair(dis[v], v));
    209             }
    210         }
    211     }
    212 }
    213 
    214 int main()
    215 {
    216     int a, b, c;
    217     while(~scanf("%d%d", &N, &M))
    218     {
    219         if(N == 0 && M == 0) break;
    220         init();
    221         while(M--)
    222         {
    223             scanf("%d%d%d", &a, &b, &c);
    224             add(a, b, c);
    225             add(b, a, c);
    226         }
    227 
    228         dij();
    229         printf("%d
    ", dis[N]);
    230     }
    231 
    232     return 0;
    233 }
    复制代码
  • 相关阅读:
    winform中利用正则表达式得到有效的电话/手机号
    winform运行时如何接受参数?(示例)
    [基础]Javascript中的继承示例代码
    [转]C#中"is" vs "as"
    Javascript数组常用方法[包含MS AJAX.NET的prototype扩展方法]示例
    linq学习笔记(一)
    用winform应用程序登录网站的解决方案
    [转贴]操纵自如--页面内的配合与通信
    .net3.0中的扩展方法(示例)
    window.location或window.open如何指定target?
  • 原文地址:https://www.cnblogs.com/DWVictor/p/10325952.html
Copyright © 2020-2023  润新知