• 算法笔记--数据结构--图-最短路径


    Dijkstra算法

    迪杰斯特拉算法用来解决单源最短路问题,即给的图G和起点s,通过算法得到s到达其他每个顶点的最短距离

    概念

    基本思想:对图G(V,E)设置集合S,存放已被访问顶点,然后每次从集合V - S中选择与起点s的最短距离最小的一个顶点(记为u),访问并加入集合S。之后,令顶点u为中介点,优化起点s与所有从u能到达的顶点v之间的最短距离,操作n次(n为顶点数),直到集合S包含所有顶点

    例子

    Snipaste_2020-04-20_11-44-18

    Snipaste_2020-04-20_11-44-25

    邻接矩阵

    #include<cstdio>
    
    const int MAXV = 1000;
    const int INF = 100000000;
    
    int n, G[MAXV][MAXV];
    int dist[MAXV];
    bool vis[MAXV] = {false};
    
    void Dijkstra(int s){
        fill(dist, dist + MAXV, INF);
        dist[s] = 0;
        for(int i = 0; i < n; i++){
            int u = -1, MIN = INF;
            for(int j = 0; j < n; j++){
                if(vis[j] == false && dist[j] < MIN){
                    u = j;
                    MIN = dist[u];
                }
            }
            
            if(u == -1) return;
            vis[u] = true;
            for(int v = 0; v < n; v++){
                if(vis[v] == false && G[u][v] != INF && dist[u] + G[u][v] < dist[v]){
                    dist[v] = dist[u] + G[u][v];
                }
            }
        }
    }
    

    邻接表

    #include<cstdio>
    #include<vector>
    using namespace std;
    const int MAXV = 1000;
    const int INF = 100000000;
    
    struct node{
        int v, dist; // v为边的目标顶点,dis为边权
    };
    
    int n;
    vector<node> Adj[MAXV];
    int dist[MAXV];
    bool vis[MAXV] = {false};
    
    void Dijkstra(int s){
        fill(dist, dist + MAXV, INF);
        dist[s] = 0;
        for(int i = 0; i < n; i++){
            int u = -1, MIN = INF;
            for(int j = 0; j < n; j++){
                if(vis[j] == false && dist[j] < MIN){
                    u = j;
                    MIN = dist[j];
                }
            }
            if(u == -1) return;
            vis[u] = true;
            for(int j = 0; j < Adj[u].size(); j++){
                int v = Adj[u][j].v;
                if(vis[v] == false && dist[u] + Adj[u][j].dist < dist[v]){
                    dist[v] = dist[u] + Adj[u][j].dist;
                }
            }
        }
    }
    

    以上所计算的是最短路径,为了计算得到最短路径,设置pre[]数组,令pre[v]表示从起点s到顶点v的最短路径上v的前一个顶点(即前驱结点)的编号

    #include<cstdio>
    
    const int MAXV = 1000;
    const int INF = 100000000;
    
    int n, G[MAXV][MAXV];
    int dist[MAXV];
    int pre[MAXV];
    bool vis[MAXV] = {false};
    
    void Dijkstra(int s){
        fill(dist, dist + MAXV, INF);
        dist[s] = 0;
        for(int i = 0; i < n; i++){
            int u = -1, MIN = INF;
            for(int j = 0; j < n; j++){
                if(vis[j] == false && dist[j] < MIN){
                    u = j;
                    MIN = dist[u];
                }
            }
            
            if(u == -1) return;
            vis[u] = true;
            for(int v = 0; v < n; v++){
                if(vis[v] == false && G[u][v] != INF && dist[u] + G[u][v] < dist[v]){
                    dist[v] = dist[u] + G[u][v];
                    pre[v] = u;			// 记录v的前驱顶点是u(新添加)
                }
            }
        }
    }
    

    之后,利用递归来求出整条路径:

    void DFS(int s, int v){		// s为起点编号,v为当前访问的顶点编号
        if(s == v){
            printf("%d
    ", s);
            return;
        }
        DFS(s, pre[v]);
        printf("%d
    ", v);
    }
    

    Snipaste_2020-04-20_14-36-18

    三种常见题型

    Snipaste_2020-04-20_14-37-39

    Snipaste_2020-04-20_14-37-47

    Snipaste_2020-04-20_14-38-46

    Snipaste_2020-04-20_14-38-54

    Write by Gqq

  • 相关阅读:
    创建windows服务
    Scrum演练(2)
    数据结构链表创建与输出
    C++ XML解析之tinyXML
    解决VS2010启动速度死慢的问题
    标准C++中string类的用法总结
    模版参数编译时检查方法,利用typedef
    static的作用
    数据结构实现链表的反转
    字节对齐
  • 原文地址:https://www.cnblogs.com/zgqcn/p/12783440.html
Copyright © 2020-2023  润新知