单源最短路径(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 */
相关文章推荐
- 【转】C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素
- OC4_实例变量的作用域
- 【转】Bash中的shopt选项
- android源码编译环境的准备及编译之后使用emulator运行的方法 - 官方版
- 文本编辑器 markdown
- SAT数学答题方法分享
- 算法导论第三章--- 渐进记号
- log4jdbc实现慢查询sql记录
- C# 下拉框绑定数据
- 图数数据库引擎tinkerpop(3) 使用java调用tinkerpop,存储到mysql数据库
- Android学习4、Android该Adapter
- OC3_选择器
- mac下搭建discuz论坛
- Android中如何查看内存(上)
- App工具大杂烩,五花八门闹创业(武汉站)
- Dll导出对话框导致内存泄露
- ubuntu安装chrome
- 解决找不到动态库libpthread.so
- 使用OpenCVC随机森林
- 协同过滤推荐算法