图论中最短路径问题C++实现

15 篇文章 0 订阅
12 篇文章 0 订阅
City.h文件
    #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) {}  
}  
;  
  
#endif 
RoadSystem.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  


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值