📜  Dijkstra最短路径算法的C C++程序|英特尔®开发人员专区贪婪的算法7(1)

📅  最后修改于: 2023-12-03 14:40:43.853000             🧑  作者: Mango

Dijkstra最短路径算法的C/C++程序

算法介绍

Dijkstra算法用于解决带权有向图的最短路径问题,例如网络路由等。

该算法利用贪心思想,每次从起点选择当前最短路径可以到达的未标记节点,直到到达终点。

算法流程
  1. 初始化距离数组为INF,起点距离设为0;
  2. 遍历所有未标记节点中距离起点最近的节点,标记该节点;
  3. 更新起点到所有未标记节点的距离,并记录路径;
  4. 重复2~3,直到到达终点或所有节点都被标记。
C/C++程序
定义头文件和宏定义
#include<iostream>    //输入输出头文件
#include<cstring>    //字符串头文件
#include<algorithm>   //STL头文件
using namespace std;

const int MAX = 1005;   //最大节点数
const int INF = 0x3f3f3f3f;  //无限大
定义边类和最短路径类
//边类
class Edge{
private:
    int v, w;  //边的终点和权值
public:
    Edge(){}   //构造函数
    Edge(int v, int w):v(v),w(w){}
    int getV(){return v;}   //返回边的终点
    int getW(){return w;}   //返回边的权值
};

//最短路径类
class ShortestPath{
private:
    int n, s;    //节点数和起点
    int dis[MAX];    //距离数组
    int pre[MAX];    //前驱数组
    bool vis[MAX];   //标记数组
    vector<Edge> G[MAX];   //邻接表表示图
public:
    ShortestPath(int n, int s):n(n),s(s){}
    void addEdge(int u, int v, int w){  //添加边
        G[u].push_back(Edge(v,w));
    }
    void dijkstra(){    //Dijkstra算法
        memset(vis,false,sizeof(vis));
        memset(pre,-1,sizeof(pre));
        fill(dis,dis+n,INF);
        dis[s] = 0;
        for(int i=0; i<n; i++){
            int u = -1;   //找到距离最小的节点
            for(int j=0; j<n; j++){
                if(!vis[j] && (u==-1 || dis[j]<dis[u]))
                    u = j;
            }
            vis[u] = true;
            for(int j=0; j<G[u].size(); j++){   //更新距离
                int v = G[u][j].getV();
                if(!vis[v] && dis[u]+G[u][j].getW()<dis[v]){
                    dis[v] = dis[u]+G[u][j].getW();
                    pre[v] = u;
                }
            }
        }
    }
    void printPath(int u){   //打印路径
        if(pre[u]!=-1) printPath(pre[u]);
        printf("%d ",u);
    }
    void printDis(int u){   //打印距离
        printf("%d",dis[u]);
    }
};
主函数测试
int main(){
    int n = 5, s = 0;   //节点数和起点
    ShortestPath sp(n,s);   //创建最短路径类
    sp.addEdge(0,1,2); sp.addEdge(0,2,4);
    sp.addEdge(1,2,1); sp.addEdge(1,3,7); sp.addEdge(2,3,3); sp.addEdge(2,4,5);
    sp.addEdge(3,4,1);
    sp.dijkstra();   //求最短路径
    sp.printPath(4);   //打印路径
    printf("\n");
    sp.printDis(4);   //打印距离
    printf("\n");
    return 0;
}
Markdown格式代码片段
```C++
#include<iostream>    //输入输出头文件
#include<cstring>    //字符串头文件
#include<algorithm>   //STL头文件
using namespace std;

const int MAX = 1005;   //最大节点数
const int INF = 0x3f3f3f3f;  //无限大

//边类
class Edge{
private:
    int v, w;  //边的终点和权值
public:
    Edge(){}   //构造函数
    Edge(int v, int w):v(v),w(w){}
    int getV(){return v;}   //返回边的终点
    int getW(){return w;}   //返回边的权值
};

//最短路径类
class ShortestPath{
private:
    int n, s;    //节点数和起点
    int dis[MAX];    //距离数组
    int pre[MAX];    //前驱数组
    bool vis[MAX];   //标记数组
    vector<Edge> G[MAX];   //邻接表表示图
public:
    ShortestPath(int n, int s):n(n),s(s){}
    void addEdge(int u, int v, int w){  //添加边
        G[u].push_back(Edge(v,w));
    }
    void dijkstra(){    //Dijkstra算法
        memset(vis,false,sizeof(vis));
        memset(pre,-1,sizeof(pre));
        fill(dis,dis+n,INF);
        dis[s] = 0;
        for(int i=0; i<n; i++){
            int u = -1;   //找到距离最小的节点
            for(int j=0; j<n; j++){
                if(!vis[j] && (u==-1 || dis[j]<dis[u]))
                    u = j;
            }
            vis[u] = true;
            for(int j=0; j<G[u].size(); j++){   //更新距离
                int v = G[u][j].getV();
                if(!vis[v] && dis[u]+G[u][j].getW()<dis[v]){
                    dis[v] = dis[u]+G[u][j].getW();
                    pre[v] = u;
                }
            }
        }
    }
    void printPath(int u){   //打印路径
        if(pre[u]!=-1) printPath(pre[u]);
        printf("%d ",u);
    }
    void printDis(int u){   //打印距离
        printf("%d",dis[u]);
    }
};

int main(){
    int n = 5, s = 0;   //节点数和起点
    ShortestPath sp(n,s);   //创建最短路径类
    sp.addEdge(0,1,2); sp.addEdge(0,2,4);
    sp.addEdge(1,2,1); sp.addEdge(1,3,7); sp.addEdge(2,3,3); sp.addEdge(2,4,5);
    sp.addEdge(3,4,1);
    sp.dijkstra();   //求最短路径
    sp.printPath(4);   //打印路径
    printf("\n");
    sp.printDis(4);   //打印距离
    printf("\n");
    return 0;
}