最短路径问题

75 阅读2分钟

图的最短路径

1.单源点最短路径

对于给定的有向图G=(V,E)和单源点VsV_s,求出VsV_s与V中其余各点的最短路径

Dijkstra算法

  • 把图中的点分为两组
    • 一组为已加入最短路径的点
    • 一组为还为加入最短路径的点
  • 将第二组中按距VsV_s距离的递增顺序不断把第二组中的点并入第一组中
    • 每次并入之后,第二组剩下的点与VsV_s的距离可能会发生变化(for example:VkV_k is the emerged dot,VjV_j is a remaining dot in the second group,if dist( VsV_s,VjV_j ) more than the dist( VkV_k,VjV_j )+dist(VsV_s,VkV_k),then you have to update the VjV_j),so we have to update the dist array. hint:Dijkstra algorithm is similar to Prim algorithm.

here is the code

#include<vector>
#include<iostream>
using namespace std;
//use adjacency matrix to memory the graph
const int INF = 0x3f3f3f3f; //to avoid overflow, this num can't be big
void dijkstra(vector<vector<int>> edges,vector<int>& distance,vector<int>& pre ,int n,int start){
    bool visited[n+1]; // to mark which dot is in first group
    for(int i = 1;i<=n;i++){
        visited[i] = false;
        distance[i] = INF;
        pre[i] = -1;
    }
    distance[start] = 0;
    for(int i = 1;i<=n;i++){
        int index = -1;
        int min = INT_MAX;
        for(int j = 1;j<=n;j++){ // to find the dot whose distance between first group is minimal
            if(!visited[j] && distance[j]<min){
                min = distance[j];
                index = j;
            }
        }
        if(index == -1){
            break;
        }
        visited[index] = true;
        for(int j = 1;j<=n;j++){ //update the remaining dot's distance between first group
            if(!visited[j] && distance[index]+edges[index][j] < distance[j]){
                distance[j] = distance[index]+edges[index][j];
                pre[j] = index;
            }
        }    
    }
}
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> edges(n+1,vector<int>(n+1,INF));
    vector<int> distance(n+1,INF);
    vector<int> pre(n+1,-1);
    for(int i = 0;i<m;i++){
        int x,y,w;
        cin>>x>>y>>w;
        edges[x][y]=w;
    }
    int start;
    cin>>start;
    dijkstra(edges,distance,pre,n,start);
    for(int i = 1;i<=n;i++){
        cout<<"distance:"<<distance[i]<<" ";
        cout<<"path:"<<i;
        int head = i;
        while(pre[head] != -1){
            cout<<"->"<<pre[head];
            head = pre[head];
        }
        cout<<endl;
    }
    return 0;
}

here is an example:\

2023-12-21-01-03-25.png

每一对顶点间最短路径

For any given directed graph G=(V,E),find out the shortest path of any pair of vertexs.
There are also other algorithms like Floyd algorithm which is similar to Dijkstra algorithm. Here omit details.