Data Structure - Djikstra's shortest path algorithm shown in (Dijkstra)

A. Djikstra defined algorithm

  1. 形式:For single-source shortest path problem, i.e., given a graph G, and the starting point s, the shortest distance algorithm by each vertex.
  2. 基本思想:Setting the set S of FIG. G (V, E), storing vertices have been visited, and then select the shortest distance from each of a start point s vertex u minimum VS from the collection, the access to the collection and S. After that, make vertex u as an intermediary point, optimizing the shortest distance between the starting point and all u can reach from the vertex v. This operation is performed n (number of vertices) times.
  3. 伪代码:
//G为图, 一般设置为全局变量,数组d为源点到达各点的最短路径长度,s为起点
Djikstra(G, d[], s){
    初始化
    for(循环n次){
        u = 是d[u]最小的还未被访问的顶点的标号
        记u已被访问
        for(从u出发能到达的所有顶点v){
            if(v未被访问&&以U为中介使得s到顶点v的最短距离d[v]更优){
                优化d[v]
            }
        }
    }
}

Second, the specific implementation

1. adjacency matrix version
const int MAXV = 1000;//最大顶点数
const int INF = 10000000000;//设INF为一个很大数

//适用于点数不大的情况
int n, G[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV];

void Dijkstra(int s){
    fill(d, d+MAXV, INF);
    d[s] = 0;
    for(int i = 0; i < n; i++){
        int u = -1. MIN = INF;//u使d[u]最小, MIN存放该最小d[u]
        for(int j = 0; j < n; j++){
            if(vis[j] == false && d[j] < MIN){
                u = j;
                MIN = d[j];
            }
        }
        //找不到小于INF的d[u],说明剩下的顶点与s不连通
        if(u == -1) return;
        vis[u] = true;//标记u为已访问
        for(int v = 0; v < n; v++){
            //如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
            if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
                d[v] = d[u] + G[u][v];//优化d[v]
            }
        }
    }
}
2. adjacency list version
struct node{
    int v, dis;//v为边的目标顶点,dis为边权
};

vector<node> Adj[MAXV];
int n;
int d[MAXn];
bool vis[MAXV] = {false};

void Dijkstra(int s){
    fill(d, d+MAXV, INF);
    d[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 && d[j] < MIN){
                u = j;
                MIN = d[j];
            }
        }
        if(u == -1) return;
        vis[u] = true;
        //只有这个部分与邻接矩阵自而发不同
        for(int j = 0; j < Adj[u].size(); j++){
            int v = Adj[u][j].v//通过邻接表直接获得u能够到达的v
            if(vis[v] == false && d[u] + Adj[u][j].dis < d[v]){
                d[v] = d[u] + Adj[u][j].dis;
            }
        }
    }
}
3. The method for finding the shortest path (on the basis of the above)
  • If the title is given undirected graph, it can be changed according to their own adjacency list and adjacency matrix, if the adjacency matrix can be simultaneously adding the same weight on both sides; adjacency table if it is so used push_back, while also exchanging input .
<1> In Example adjacency matrix
const int MAXV = 1000;//最大顶点数
const int INF = 10000000000;//设INF为一个很大数

//适用于点数不大的情况
int n, G[MAXV][MAXV];
int d[MAXV];
bool vis[MAXV];
int pre[MAXV];//表示从起点到顶点v的最短路径上v的前一个顶点(新添加)
void Dijkstra(int s){
    fill(d, d+MAXV, INF);
    d[s] = 0;
    for(int i = 0; i < n; i++){
        int u = -1. MIN = INF;//u使d[u]最小, MIN存放该最小d[u]
        for(int j = 0; j < n; j++){
            if(vis[j] == false && d[j] < MIN){
                u = j;
                MIN = d[j];
            }
        }
        //找不到小于INF的d[u],说明剩下的顶点与s不连通
        if(u == -1) return;
        vis[u] = true;//标记u为已访问
        for(int v = 0; v < n; v++){
            //如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
            if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
                d[v] = d[u] + G[u][v];//优化d[v]
                //就是在这里改变,添加了一条语句
                pre[v] = u;//新添加
            }
        }
    }
}

//如何打印,就是递归打印
void dfs(int s, int v){
    if(v == s){
        printf("%d\n", s);
        return;
    }
    dfs(s, pre[v]);
    printf("%d\n", v);
}
4. Other cases occur, i.e., additional conditions
  • Appears in addition to the first shortest path conditions, there may be other conditions, if a plurality of paths
  • Each side adds a right side (spending);
  • Each point add a point right (such as supplies each city can receive);
  • Directly asked how many shortest path.
<1> new right side. The right side to add spending, for example, are in the final judgment to be modified, the rest were without changes
        for(int v = 0; v < n; v++){
            //如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
            if(vis[v] == false && G[u][v] != INF){
                if(d[u] + G[u][v] < d[v]){
                     d[v] = d[u] + G[u][v];//优化d[v]
                     c[v] = c[u] + cost[u][v];
                }else if(d[u] + G[u][v] == d[v] && c[u] + cost[u][v] < c[v]){
                    c[v] = c[u] + cost[u][v];
                }
            }
        }
<2> to add the right point to the right point on behalf of the new material can be collected in cities, for example, u represents the number of cities in materials with weight [u], and adds an array W [], to make it as a starting point s to reach the maximum material W [u] may be collected vertex u.
        for(int v = 0; v < n; v++){
            //如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
            if(vis[v] == false && G[u][v] != INF){
                if(d[u] + G[u][v] < d[v]){
                     d[v] = d[u] + G[u][v];//优化d[v]
                     w[v] = w[u] + weight[v];
                }else if(d[u] + G[u][v] == d[v] && w[u] + weight[v] > w[v]){
                    w[v] = w[u] + weight[v];
                }
            }
        }
<3> required number of shortest path. Only need to add an array num [], the initial num [s] = 1, the rest are num [u] = 0.
        for(int v = 0; v < n; v++){
            //如果v未访问&&u能够到达v&&以u为中介点可以使d[v]更优
            if(vis[v] == false && G[u][v] != INF){
                if(d[u] + G[u][v] < d[v]){
                     d[v] = d[u] + G[u][v];//优化d[v]
                     num[v] = num[u];
                }else if(d[u] + G[u][v] == d[v]){
                    num[v] += num[u];
                }
            }
        }

Guess you like

Origin www.cnblogs.com/tsruixi/p/12380430.html