图论中最短路径问题C++实现
2016-12-10 18:59
661 查看
City.h文件
Road.h文件
RoadSystem.cpp文件
main.cpp文件
MapInformation.txt文件
#ifndef _CITY_H_ #define _CITY_H_ using namespace std; class City { public: // 城镇的名称 string name; // 簿记信息 bool visited; int total_fee; int total_distance; string from_city; //默认构造函数 City() : name(""), visited(false), total_fee(0), total_distance(0), from_city("") {} City(string const &s): name(s), visited(false), total_fee(0), total_distance(0), from_city("") {} }; #endif
Road.h文件
#ifndef _ROAD_H_ #define _ROAD_H_ #include <string> using namespace std; class Road { public: int fee; int distance; string destination; Road(string city, int f, int d) : fee(f), distance(d), destination(city) {} } ; #endifRoadSystem.h文件
#ifndef _ROADSYSTEM_H_ #define _ROADSYSTEM_H_ #include <iostream> #include <fstream> #include <map> #include <list> #include <queue> #include <vector> #include "Road.h" #include "City.h" using namespace std; class Cheapest { public: Cheapest() {} bool operator()(City* city1, City* city2) { return city1->total_fee > city2->total_fee; } }; class RoadSystem { private: map<string, list<Road*> > outgoing_roads; map<string, City*> cities; void load_roads(const string& filename); void reset(void); string recover_route(const string& city); pair<int, int> calc_route(string from, string to); public: RoadSystem(const string& filename);//带参数的构造函数,从文件中读取地图信息 ~RoadSystem(void);//析够函数 void output_cheapest_route(const string& from, const string& to, ostream& out); bool is_valid_city(const string& name); }; #endif
RoadSystem.cpp文件
派生到我的代码片 #pragma warning (disable:4786) #pragma warning (disable:4503) #include "RoadSystem.h" void RoadSystem::reset(void) { map<string, City*>::iterator it; for(it=cities.begin();it!=cities.end();++it) { it->second->visited = false; it->second->total_fee = INT_MAX; it->second->total_distance = INT_MAX; it->second->from_city = ""; } } string RoadSystem::recover_route(const string& city) { string route; string current = city; while (current != "") { route = current + route; string prev = cities[current]->from_city; if (prev != "") { route = " -> " + route; } current = prev; } return route; } RoadSystem::RoadSystem(string const &filename) { load_roads(filename); } RoadSystem::~RoadSystem(void) { // 释放城市信息 map<string, City*>::iterator city_it = cities.begin(); for ( ; city_it != cities.end(); city_it++) { delete city_it->second; } // 释放道路信息 map<string, list<Road*> >::iterator roads_it = outgoing_roads.begin(); for ( ; roads_it != outgoing_roads.end(); roads_it++) { list<Road*>::iterator road_it = roads_it->second.begin(); for ( ; road_it != roads_it->second.end(); road_it++) { delete *road_it; } } } void RoadSystem::load_roads(string const &filename) { ifstream inf(filename.c_str()); string from, to; int fee, distance; while ( inf.good() ) { // 读入出发城市,目的城市,费用和路程信息 inf >> from >> to >> fee >> distance; if ( inf.good() ) { Road* s = new Road(to, fee, distance); // 在cities容器中加入实体 if (cities.count(from) == 0) { cities[from] = new City(from); outgoing_roads[from] = list<Road*>(); } if (cities.count(to) == 0) { cities[to] = new City(to); outgoing_roads[to] = list<Road*>(); } // 为城市添加道路 outgoing_roads[from].push_back(s); } } inf.close(); } //输出结果 void RoadSystem::output_cheapest_route(const string& from, const string& to, ostream& out) { reset(); pair<int, int> totals = calc_route(from, to); if (totals.first == INT_MAX) { out <<"从"<< from << "到" << to << "之间不存在可达的路径。"<<endl; } else { out << "从" << from << "到" << to << "之间最便宜的路径需要花费"<< totals.first << "澳元。"<<endl; out << "该路线全长" << totals.second << "千米。" <<endl; cout << recover_route(to) << endl << endl; } } bool RoadSystem::is_valid_city(const string& name) { return cities.count(name) == 1; } //迪克斯特拉算法计算最短路径 pair<int, int> RoadSystem::calc_route(string from, string to) { // 用优先队列来获得下一个费用最低的城市 priority_queue<City*, vector<City*>, Cheapest> candidates; City* start_city = cities[from]; // 将起始城市添加到队列中 start_city->total_fee = 0; start_city->total_distance = 0; candidates.push(start_city); // 如果优先队列不空则循环 while(!candidates.empty()) { City* visiting_city; visiting_city = candidates.top(); candidates.pop(); if (! visiting_city->visited) { visiting_city->visited = true; // 循环检查与该城市相连的各条公路 list<Road*>::iterator it; for(it= outgoing_roads[visiting_city->name].begin(); it != outgoing_roads[visiting_city->name].end(); ++it) { City* next_city = cities[(*it)->destination]; int next_fee = (*it)->fee + visiting_city->total_fee; // 迪克斯特拉算法修改标记处 if((next_fee < next_city->total_fee) && next_city->name != from ) { next_city->total_fee = next_fee; next_city->total_distance = (*it)->distance + visiting_city->total_distance; next_city->from_city = visiting_city->name; candidates.push(next_city); } } } } // 返回总的费用和总的路程 if (cities[to]->visited) { return pair<int,int>(cities[to]->total_fee, cities[to]->total_distance); } else { return pair<int,int>(INT_MAX, INT_MAX); } }
main.cpp文件
派生到我的代码片 #pragma warning (disable:4786) #pragma warning (disable:4503) #include <iostream> #include <fstream> #include <string> #include <list> #include <map> #include <queue> #include "City.h" #include "Road.h" #include "RoadSystem.h" using namespace std; int main() { try { RoadSystem rs("MapInformation.txt"); while (true) { cerr << endl << endl <<"请输入起点城市和终点城市: (退出请输入'quit')"<<endl; string from, to; cin >> from; if (from == "quit") break; cin >> to; if (rs.is_valid_city(from) && rs.is_valid_city(to)) { rs.output_cheapest_route (from, to, cout); } else { cout << "无此城市, 请确认后重试!"<<endl<<endl; } } return EXIT_SUCCESS; } catch (exception& e) { cerr << e.what() << endl; } catch (...) { cerr << "程序出现异常, 请退出程序后重试。"<<endl; } return EXIT_FAILURE; }
MapInformation.txt文件
Deloraine Queenstown 42 176 Deloraine Oatlands 25 84 Deloraine Launceston 12 50 Hobart Oatlands 18 84 Launceston Deloraine 12 50 Launceston Swansea 35 134 Oatlands Deloraine 25 84 Oatlands Hobart 18 84 Oatlands Queenstown 60 260 Oatlands Swansea 22 113 Queenstown Oatlands 60 260 Queenstown Deloraine 42 176 Swansea Launceston 35 134 Swansea Oatlands 22 113 Burnie Devonport 10 49 Devonport Burnie 10 49
相关文章推荐
- 最短路径问题——Dijkstra算法(C++实现)
- 用c++代码实现贪心算法求解最短路径问题
- c++中关于最短路径问题的Dijkstra算法的实现
- C++ 求最短路径问题之Dijkstra算法(一)
- Floyd-Warshall算法求解所有结点对的最短路径问题Java实现
- C++实现多源最短路径之Floyd算法示例
- 【图论】最短路径&&最小生成树问题
- 狄克斯特拉算法,解决加权最短路径问题--python实现
- 图论--最短路径问题--Dijkstra算法和Floyd算法
- 最短路径问题-Graph Java实现
- 图论-最短路径问题
- 单源最短路径问题(dijkstra算法 及其 优化算法(优先队列实现))
- 每对顶点间的最短路径C++实现
- 每对顶点间的最短路径算法时间复杂度改进C++实现
- 复杂迷宫问题的递归实现以及最短路径
- 01背包、完全背包、多重背包问题的C++实现及路径记录
- 图论-最短路径-spfa两种实现方式-poj3259
- ssl1613-最短路径问题【图论,最短路径(还不明显?)】
- 3.10 用栈实现解决迷宫问题(输出一条路径(非最短路径))
- 最短路径问题:Dijkstra算法的python实现