zoukankan      html  css  js  c++  java
  • 最短路算法模板合集(Dijkstar,Dijkstar(优先队列优化), 多源最短路Floyd)

    再开始前我们先普及一下简单的图论知识

    图的保存:

    1.邻接矩阵。 G[maxn][maxn];

    2.邻接表

    邻接表我们有两种方式

    (1)vector< Node > G[maxn];

    这个是之前就定义了图的大小了,再下面使用的时候就不用对图的大小进行申请了, 但是因为是直接申请了大小

    要对图进行初始化,因此可能在某些题目中这样使用的话会超时

    (2)vector< vector<Node> > G;

    这个是未定义大小,但是在使用之前要对其的大小内存进行申请。

     G.resize(n+1);

    Dijkstra's Algorithm

    算法思想:

    1.从源点出发源点所有能一步到达的点的距离更新,然后从除源点外的所有点之中找出距离源点最近的点。

    2.然后更新我们之前所找到的最短路点所有连接的点,但是要求这个点未曾被当做最短点处理过

    3.重复上述操作n次。

    单源最短路 我们还可以对他进行优先队列优化下面是以HDU2544为模板的用Dijkstra's Algorithm 

    邻接矩阵版,不用优先队列优化

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    #define INF 0xfffffff
    #define maxn 1002
    
    int G[maxn][maxn];//保存图
    int dist[maxn];//表示从起点到第i点的距离
    bool vis[maxn];//判断这个点是否被参观过
    int m, n;//边数 m   顶点数 n
    
    void Init()
    {
        for(int i=0; i<=n; i++)
        {
            vis[i] = false;
            dist[i] = INF;
            for(int j=0; j<=i; j++)
                G[i][j] = G[j][i] =  INF;
        }
    }
    int Dij(int Star,int End)//起点 --- 终点
    {
        dist[Star] = 0;
        for(int i=1; i<=n; i++)
        {
            int index = 0, Min = INF;
            for(int j=1; j<=n; j++)
            {
                if( !vis[j] && Min > dist[j] )//找出没有被参观过,并且距离起点最近的点
                    Min = dist[j], index = j;
            }
    
            vis[index] = true;
    
            for(int j=1; j<=n; j++)//更新所有未曾到达的点距离,使之成为最近的点
            {
                if( !vis[j] && dist[j] >  dist[index] + G[index][j] )
                    dist[j] = dist[index] + G[index][j];
            }
        }
    
        return dist[End];
    
    }
    
    int main()
    {
        while(cin >> n >> m, m + n)
        {
            Init();
    
            int a, b , c;
    
            for(int i=0; i<m; i++)
            {
                cin >> a >> b >> c;
                G[a][b] = min(G[a][b], c);
                G[b][a] = G[a][b];
            }
    
            int ans = Dij(1,n);
    
            cout << ans << endl;
        }
        return 0;
    }
    

      接下来是邻接表版,用到了优先队列优化

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cstdio>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 using namespace std;
    10 #define INF 0xfffffff
    11 #define maxn 1002
    12 
    13 struct Node
    14 {
    15     int e;
    16     int w;
    17     friend bool operator < (Node A, Node B)
    18     {
    19         return  A.w > B.w;
    20     }
    21 };
    22 
    23 bool vis[maxn];
    24 
    25 int m, n;
    26 vector< vector<Node> > G;
    27 
    28 int Dij(int Star,int End)
    29 {
    30     Node P, Pn;
    31     P.e = Star;
    32     P.w = 0;
    33 
    34     priority_queue<Node> Q;
    35 
    36     Q.push(P);
    37 
    38     while( !Q.empty() )
    39     {
    40         P = Q.top();
    41         Q.pop();
    42 
    43         if( vis[P.e] )
    44             continue;
    45 
    46         vis[P.e] = true;
    47 
    48         if( P.e == End )
    49             return P.w;
    50 
    51         int len = G[P.e].size();
    52 
    53         for(int i=0; i< len; i++)
    54         {
    55             Pn.e = G[P.e][i].e;
    56             Pn.w = G[P.e][i].w + P.w;
    57 
    58             if( !vis[Pn.e] )
    59                 Q.push(Pn);
    60         }
    61     }
    62     return -1;
    63 }
    64 
    65 int main()
    66 {
    67     Node P;
    68     while(cin >> n >> m, m+n)
    69     {
    70         G.clear();
    71         G.resize(n+1);
    72 
    73         memset(vis,false,sizeof(vis));
    74 
    75         for(int i=0; i<m; i++)
    76         {
    77             int a, b, c;
    78             cin >> a >> b >> c;
    79             P.e = b;
    80             P.w = c;
    81             G[a].push_back(P);
    82             P.e = a;
    83             G[b].push_back(P);
    84         }
    85 
    86         int ans = Dij(1,n);
    87 
    88         cout << ans << endl;
    89     }
    90     return 0;
    91 }

    下面是Floyd算法

    Floyd是求多源最短路, 即可以求出所有点对之间的最短路

    这个算法就只要注意两点就行了,初始化的时候 G[i][i] = 0, 其他的初始化为INF

    #include <iostream>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    #define INF 0xfffffff
    #define maxn 1002
    
    int G[maxn][maxn];
    int dist[maxn][maxn];
    int m, n;
    
    void Floyd()
    {
        for(int k=1; k<=n; k++)
        {
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
                }
            }
        }
    }
    void Init()
    {
        for(int i=0; i<=n; i++)
        {
            G[i][i] = 0;
            for(int j=0; j<i; j++)
                G[i][j] = G[j][i] = INF;
        }
    }
    
    int main()
    {
        while(cin >> n >> m, m+n)
        {
            Init();
            for(int i=0; i<m; i++)
            {
                int a, b, c;
                cin >> a >> b >> c;
                G[a][b] = min(G[a][b],c);
                G[b][a] = G[a][b];
            }
    
            Floyd();
    
            cout << G[1][n] << endl;
        }
        return 0;
    }
  • 相关阅读:
    JAVA设计模式---总述篇
    Java中对象创建时的内存分配
    for循环打印空心菱形的新方法
    springcloud2.X通过actuator加载配置无效问题
    golang-错误处理
    golang-字符串
    golang-方法和接口
    golang-结构体与指针
    golang-数组、切片、映射
    golang-流程控制
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4143071.html
Copyright © 2011-2022 走看看