您的位置:首页 > 其它

单源最短路径(dijkstra算法)

2015-06-16 16:35 309 查看
#include <iostream>
#include <queue>
#include <map>
#include <utility>
#include <climits>
using namespace std;

typedef int graph_weight_t;
typedef char graph_vertex_id_t;
struct graph_t {
    int nv; 
    int ne; 
    map<graph_vertex_id_t, map<graph_vertex_id_t, graph_weight_t> > matrix;
};
/**
* @param[in] start 起点
* @param[out] dist dist[v] 存放的是起点到v 的最短路径长度
* @param[out] father father[v] 存放的是最短路径上指向v 的上一个顶点
*/
void dijkstra(const graph_t &g, graph_vertex_id_t start,
              map<graph_vertex_id_t, graph_weight_t> &distance,
              map<graph_vertex_id_t, graph_vertex_id_t> &father) {
        /* 起点到顶点的最短距离. */
        typedef pair<graph_weight_t, graph_vertex_id_t> to_dist_t;
        // 小根堆
        priority_queue<to_dist_t, vector<to_dist_t>, greater<to_dist_t> > q;
        distance[start] = 0; // 自己到自己,距离为0
        q.push(to_dist_t(0, start));
        while (!q.empty()) {
            const to_dist_t u = q.top(); q.pop();
            if (g.matrix.find(u.second) == g.matrix.end()) continue;
            for (map<graph_vertex_id_t, graph_weight_t>::const_iterator iter =
                g.matrix.at(u.second).begin();
                iter != g.matrix.at(u.second).end(); ++iter) {
                    const graph_vertex_id_t v = iter->first;
                    const graph_weight_t w = iter->second;
                    if (!distance.count(v) || distance[u.second] + w < distance[v]) {
                        distance[v] = distance[u.second] + w;
                        father[v] = u.second;
                        q.push(to_dist_t(distance[v], v));
                    }
            }
        }
        return;
}
/**
* @brief 打印从起点到终点的最短路径
* @param[in] father Dijkstra 计算好的father 数组
* @param[in] end 终点
*/
void print_path(const map<graph_vertex_id_t, graph_vertex_id_t> &father,
    graph_vertex_id_t end) {
        if (!father.count(end)) {
            cout << end;
        } else {
            print_path(father, father.at(end));
            cout << "->" << end;
        }
}

    /** 读取输入,构建图. */
void read_graph(graph_t &g) {
    cin >> g.ne;
    for (int i = 0; i < g.ne; ++i) {
        graph_vertex_id_t from, to;
        graph_weight_t weight;
        cin >> from >> to >> weight;
        g.matrix[from][to] = weight;
    }
}

int main() {
    graph_t g;
    map<graph_vertex_id_t, graph_weight_t> distance;
    map<graph_vertex_id_t, graph_vertex_id_t> father;
    read_graph(g);
    dijkstra(g, 'A', distance, father);
    // 输出所有路径
    for(map<graph_vertex_id_t, graph_vertex_id_t>::const_iterator iter =
        father.begin(); iter != father.end(); ++iter) {
            if (iter->first != 'A') {
                print_path(father, iter->first);
                cout << endl;
            }
    }
    return 0;
}

/* test
输入数据:
8
A C 10
A E 30
A F 100
B C 5
C D 50
D F 10
E D 20
E F 60
输出:
A->C
A->E->D
A->E
A->E->D->F
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: