C++实现最短路算法——Dijkstra算法

来源:互联网 发布:淘宝二手图形工作站 编辑:程序博客网 时间:2024/05/16 13:27

我们在生活中常常遇到最短路问题,比如电力系统和网络带宽的布置,水管与物料传输。这些问题都可以抽象成图论中的最短路问题——我们需要找到最短的路径,达到节约资源的目的。Dijkstra算法可以用于解决有向图中,所有权值为正的情况下,单源最短路问题。它可以实现计算有向图中一个点到所有点的最小路径。

下面的代码实现了这个算法,使用邻接表储存图,并封装到结构体中用于计算,便于使用:

#include <iostream>#include <algorithm>#include <vector>#include <cstring>#include <queue>#define FOR(x,f,t) for(x=f;x<=t;++x)#define RFOR(x,f,t) for(x=f;x>=t;--x)#define oo 2147483647#define M 505#define MEMSET(a,b) memset(a,b,sizeof(a));typedef long long ll;using namespace std;struct DD {    int id,dist;    DD(int i,int d):id(i),dist(d) {}    bool operator < (const DD& dd) const {         //按每点D值排序,用于下面的优先队列        return dist>dd.dist;    }};struct Edge {    int f,t,len;    Edge(int a,int b,int c):f(a),t(b),len(c) {}};struct Dijkstra {    int size;    bool taken[M];    int d[M];    vector<Edge> edges;    void init(int size) {        this->size=size;        edges.clear();    }    void addEdge(int f,int t,int len) {        edges.push_back(Edge(f,t,len));    }    void dijkstra(int s) {        MEMSET(taken,0); //清空标记        MEMSET(d,127); //将每点d值填充到无穷大        d[s]=0; //起始点d值为0        priority_queue<DD> Q;        Q.push(DD(s,0));        int i;        while(!Q.empty()) {            DD mi=Q.top(); //取出剩余点中d值最小的点            Q.pop();            int x=mi.id;            taken[x]=true;            FOR(i,0,edges.size()-1) {                Edge& e=edges[i];                if (taken[e.t]) continue;                if (e.f!=x) continue;                d[e.t]=min(d[e.t],d[x]+e.len);                Q.push(DD(e.t,d[e.t]));            }        }    }};int main() {    Dijkstra d;    int i,n,m;    cin>>n>>m; //图一共有n个点,m条边    d.init(n); //初始化    FOR(i,1,m) {        int a,b,c;        cin>>a>>b>>c;        d.addEdge(a,b,c); //添加边    }    d.dijkstra(1); //求从第1个点开始到所有点的距离    FOR(i,1,n) cout<<d.d[i]<<" ";    return 0;}

测试输入:

571 2 101 4 301 5 1002 3 503 5 104 3 204 5 60

输出:

0 10 50 30 60

可以看到,Dijkstra算法正确的输出了结果。

1 0
原创粉丝点击