最短路径 Dijkstra算法(模板)

计算最短路径的基础算法,Dijkstra算法基础模板

const int inf = 0x3f3f3f3f;
const int maxn = 1050;

struct Edge {
    int from, to, dist;
    Edge(int f, int t, int d) :from(f), to(t), dist(d) {}
};

struct HeapNode {
    int d, u;
    HeapNode(int dd, int uu) :d(dd), u(uu) {}
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m;           //点数和边数
    vector<Edge> edges; //边列表
    vector<int> g[maxn];//每个结点出发的边编号(从0开始)
    bool done[maxn];    //是否永久标号
    int d[maxn];        //s到各个点的距离
    int p[maxn];        //最短路中的上一条边

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; ++i) g[i].clear();   //清空邻接表
        edges.clear();  //清空边表
    }

    void add(int from, int to, int dist) {  //如果是无向图,每次加边调用两次
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        g[from].push_back(m - 1);
    }

    void dijkstra(int s) {  //s为源点
        priority_queue<HeapNode> que;
        for (int i = 0; i < n; ++i) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        que.push(HeapNode(0, s));
        while (!que.empty()) {
            HeapNode x = que.top();
            que.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            for (int i = 0; i < g[u].size(); ++i) {
                Edge& e = edges[g[u][i]];
                if (d[e.to] > d[u] + e.dist) {
                    d[e.to] = d[u] + e.dist;
                    p[e.to] = g[u][i];
                    que.push(HeapNode(d[e.to], e.to));
                }
            }
        }
    }
};

测试程序

#include<bits/stdc++.h>
using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 1050;

struct Edge {
    int from, to, dist;
    Edge(int f, int t, int d) :from(f), to(t), dist(d) {}
};

struct HeapNode {
    int d, u;
    HeapNode(int dd, int uu) :d(dd), u(uu) {}
    bool operator < (const HeapNode& rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    int n, m;           //点数和边数
    vector<Edge> edges; //边列表
    vector<int> g[maxn];//每个结点出发的边编号(从0开始)
    bool done[maxn];    //是否永久标号
    int d[maxn];        //s到各个点的距离
    int p[maxn];        //最短路中的上一条边

    void init(int n) {
        this->n = n;
        for (int i = 0; i < n; ++i) g[i].clear();   //清空邻接表
        edges.clear();  //清空边表
    }

    void add(int from, int to, int dist) {  //如果是无向图,每次加边调用两次
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        g[from].push_back(m - 1);
    }

    void dijkstra(int s) {  //s为源点
        priority_queue<HeapNode> que;
        for (int i = 0; i < n; ++i) d[i] = inf;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        que.push(HeapNode(0, s));
        while (!que.empty()) {
            HeapNode x = que.top();
            que.pop();
            int u = x.u;
            if (done[u]) continue;
            done[u] = true;
            for (int i = 0; i < g[u].size(); ++i) {
                Edge& e = edges[g[u][i]];
                if (d[e.to] > d[u] + e.dist) {
                    d[e.to] = d[u] + e.dist;
                    p[e.to] = g[u][i];
                    que.push(HeapNode(d[e.to], e.to));
                }
            }
        }
    }
};

int n, m, s;
Dijkstra dij;

void print(int x) {//递归打印以x为终点的最短路径
    if (x == s) {
        printf("%d", x);
        return;
    }
    Edge& e = dij.edges[dij.p[x]];
    print(e.from);
    printf(" %d", x);
}

int main() {
    while (scanf("%d%d%d", &n, &m, &s) == 3) {
        dij.init(n);
        for (int i = 0; i < m; ++i) {
            int from, to, dist;
            scanf("%d%d%d", &from, &to, &dist);
            dij.add(from, to, dist);
            dij.add(to, from, dist);
        }
        dij.dijkstra(s);

        for (int i = 0; i < n; ++i) {
            if (i == s) continue;
            printf("到点%d的最短路径:", i);
            print(i);
            printf(" 总长度:%d\n", dij.d[i]);
        }
    }
    return 0;
}

/*
5 7 0
0 1 100
0 2 30
0 4 10
2 1 60
2 3 60
3 1 10
4 3 50
*/
posted @ 2018-02-03 16:10  不想吃WA的咸鱼  阅读(220)  评论(0编辑  收藏  举报