程序设计与数据结构课程实训报告——回家之旅

回家之旅
1.问题描述
春运买票困难,有乘客想出多次中转的办法解决。试图用你学习到的数据结构与算法知识,帮助有需要的人规划回家的路线。
假设给定列车时刻信息表(包含票价情况),任意输入起点站和终点站(如广州到兰州),规划满足以下一种或者同时满足多种目标的乘车方案:
目标1:换乘次数最少【中间节点数最少的情况】;
目标2:预计耗费时间最短【让两个站点时间总加】;
目标3:票价总和最小;
目标4:卧铺优先【设置软铺、硬铺和硬座三种价格】;
目标5:错过换乘的可能性最小(因为存在晚点的可能,需考虑最短的理论换乘时间)

2.基本要求
(1)为简化相关算法,可以对问题做出一些假设,如:
简化全国的运营线路图,即改为足够多的局部的运营线路图;
对每个站点,任何一天的列车启停的情况都一样;
不考虑无票情况
(2)根据实际问题进行合理详细的需求分析
(3)功能模块划分至少包含:
输入、输出模块
数据操纵模块:如添加、修改或者删除线路、站点信息等
查询功能模块:如查询线路的相关信息
预处理模块

这篇报告是我和我的两个队友一起做的,大家认为可以打多少分,可以在评论区留言,谢谢!

#include <iostream>
#include<map>
#include<algorithm>
#include<set>
#include<vector>
#include<math.h>
#include<string>
#include<fstream>
using namespace std;
#define int long long
const int mintransfertime = 15; //理论换乘时间,以分钟为单位
const int INF = 0x3f3f3f3f; //无穷大
const string USER_PASSWORD = "654321", MANAGER_PASSWORD = "123456";
bool flag, tag, mark;
// 定义一个结构体,表示一趟列车的信息
struct Train
{
    string id; //列车编号
    string from; //起点站
    string to; //终点站
    int depart; //出发时间,以分钟为单位
    int arrive; //到达时间,以分钟为单位
    int soft; //软卧票价
    int hard; //硬卧票价
    int seat; //硬座票价
};
// 定义一个结构体,表示一条乘车方案
struct Plan
{
    vector <Train> trains; //包含的列车列表
    int cost; //总票价
    int time; //总耗时
    int transfer; //换乘次数
    int soft_cnt;//软卧的数量
    int hard_cnt;//硬卧的数量
    int seat_cnt;//硬座的数量
};
// 定义一个函数,将分钟转换为时钟格式
string format(int minutes)
{
    int hour = minutes / 60;//将分钟化为小时
    int minute = minutes % 60;//取模60剩下的就是分钟数
    string result = "";
    if (hour < 10) result += "0";
    result += to_string(hour) + ":";//将int转化为string
    if (minute < 10) result += "0";//补齐两位
    result += to_string(minute);//加上分钟
    return result;
}
// 定义一个函数,输出一条乘车方案的详细信息
void printPlan(Plan plan)
{
    cout << "总票价:" << plan.cost << "元" << endl;
    cout << "总耗时:" << format(plan.time) << endl;
    cout << "换乘次数:" << plan.transfer << endl;
    cout << "乘车详情:" << endl;
    for (int i = 0; i < plan.trains.size(); i++)//plan里面的所有乘车计划打印出来
    {
        Train train = plan.trains[i];
        cout << train.id << " " << train.from << " " << format(train.depart) << " -> " << train.to << " " << format(train.arrive) << endl;
    }
}
// 定义一个函数,比较两条乘车方案,返回较优的方案
// 优先级:总耗时>总票价>换乘次数>卧铺优先(软卧>硬卧>硬座)
Plan compare(Plan p1, Plan p2)
{
    if (p1.time < p2.time) return p1;//先比价两条路线的总耗时
    if (p1.time > p2.time) return p2;
    if (p1.cost < p2.cost) return p1;//如果时间相同比较两条路线的总花费
    if (p1.cost > p2.cost) return p2;
    if (p1.transfer < p2.transfer) return p1;//在时间花费相同的情况下,比较换乘次数
    if (p1.transfer > p2.transfer) return p2;
    if (p1.soft_cnt < p2.soft_cnt)return p1;//在以上条件都相同的情况下,比较软卧,硬卧,硬座的数量
    if (p1.soft_cnt > p2.soft_cnt)return p2;
    if (p1.hard_cnt < p2.seat_cnt)return p1;
    if (p1.hard_cnt > p2.seat_cnt)return p2;
    if (p1.seat_cnt <= p2.seat_cnt)return p1;
    else
        return p2;
}
vector <Train> timeable; //表示列车时刻信息表
vector <string> stations; //表示站点的集合
map <string, vector<Train>> adj; //表示站点之间的邻近表
//定义一个函数,初始化全局变量
void init()
{
    // 以下是示例数据,可以根据实际情况进行修改或者从文件中读取
    string s;

    string data[1010];//data用来暂时存储txt读出的数据
    ifstream infile;
    infile.open("d:\\out.txt", ios::in);
    if (!infile.is_open())//判断文件是否读取成功
    {
        cout << "文件读取失败" << endl;
        return;
    }
    vector<string>t;
    while (getline(infile, s))
    {
        s += " ";//在末尾也加上空格,保证了数据不会漏掉
        int pre = 0, cnt = 0;
        for (int i = 0; i < s.size(); i++)
        {
            if (s[i] == ' ')//以空格为分隔符进行数据分割
            {
                data[++cnt] = s.substr(pre, i - pre);//用substr函数来辅助进行分割
                pre = i + 1;//这里加一就跳过了空格,包正了数据的正确
            }
        }
        timeable.push_back({ data[1],data[2],data[3],stoi(data[4]),stoi(data[5]),stoi(data[6]),stoi(data[7]),stoi(data[8]) });
    }
    infile.close();
    //遍历时刻表,构建站点集合和邻接表
    for (int i = 0; i < timeable.size(); i++)
    {
        Train train = timeable[i];
        if (find(stations.begin(), stations.end(), train.from) == stations.end())
        {
            stations.push_back(train.from); //起点站不在站点集合中,就添加进去
        }
        if (find(stations.begin(), stations.end(), train.to) == stations.end())
        {
            stations.push_back(train.to); //终点站不在站点集合中,就添加进去
        }
        if (adj.find(train.from) == adj.end())
        {
            adj[train.from] = vector<Train>(); //起点站不在邻接表,就添加一个空的邻接表项
        }
        adj[train.from].push_back(train);
    }
}
//定义一个函数,进行深度优先搜索,寻找最优的乘车方案
void dfs(string start, string endp, Plan& best, Plan& current, vector<string>& visited)
{
    //如果当前站点是终点站,就比较当前方案和最优方案,更新最优方案
    if (start == endp)
    {
        best = compare(best, current);
        return;
    }
    //如果当前站点已经访问过,就返回
    if (find(visited.begin(), visited.end(), start) != visited.end())
    {
        return;
    }
    //将当前站点标记为已访问
    visited.push_back(start);
    //遍历当前站点的邻接表,尝试所有可能的下一趟列车
    for (int i = 0; i < adj[start].size(); i++)
    {
        Train train = adj[start][i];
        //如果当前方案为空,或者当前方案的最后一趟列车的到达时间加上最短换乘时间小于等于下一趟列车的出发时间,就可以继续搜索
        if (current.trains.empty() || current.trains.back().arrive + mintransfertime <= train.depart)
        {
            //将下一趟列车添加到当前方案中
            current.trains.push_back(train);
            //更新当前方案的总票价,总耗时,换乘次数
            int minmoney = min({ train.soft,train.hard,train.seat });//最小的花费
            current.cost += minmoney;
            if (train.soft == minmoney)//最小花费是软卧
                current.soft_cnt++;
            else if (train.hard == minmoney)//最小花费是硬卧
                current.hard_cnt++;
            else
                current.seat_cnt++;//最小花费是硬座
            if (current.trains.size() == 1) current.time += train.arrive - train.depart;//当current大小为1,应为我们在上面先push的,这时就是第一次坐车,时间就是到达时间减去出发时间
            else current.time += train.arrive - current.trains[current.trains.size() - 2].arrive;//当两列车间隔满足最小换乘时间时,时间花费就是,后一辆车到达时间,减去前一辆车的到达时间
            if (current.trains.size() != 1) current.transfer++;
            //递归地搜索下一站点
            dfs(train.to, endp, best, current, visited);
            //进行回溯,恢复现场,将数量贡献恢复
            if (train.soft == minmoney)//最小花费是软卧
                current.soft_cnt--;
            else if (train.hard == minmoney)//最小花费是硬卧
                current.hard_cnt--;
            else
                current.seat_cnt--;//最小花费是硬座
            //回溯,将下一趟列车从当前方案中移除
            current.trains.pop_back();
            //恢复当前方案的总票价,总耗时,换乘次数
            minmoney = min({ train.soft,train.hard,train.seat });
            current.cost -= minmoney;
            if (current.trains.empty()) current.time -= train.arrive - train.depart;//这里我们是先pop的和上面先push的正好反过来了
            else current.time -= train.arrive - current.trains.back().arrive;
            if (current.trains.size() != 0) current.transfer--;
        }
    }
    //将当前站点标记为未访问
    visited.pop_back();
}
//定义一个函数,根据用户的输入,规划乘车方案
void plan(string start, string endp)
{
    //如果起点站或终点站不在站点集合中,就提示用户输入有误
    if (find(stations.begin(), stations.end(), start) == stations.end())
    {
        cout << "起点站不存在,请重新输入" << endl;
        return;
    }
    if (find(stations.begin(), stations.end(), endp) == stations.end())
    {
        cout << "终点站不存在,请重新输入" << endl;
        return;
    }
    if (start == endp)
    {
        cout << "起点站和终点站相同,无需乘车" << endl;
        return;
    }
    //定义一个变量,表示最优乘车方案
    Plan best = { vector<Train>(),INF,INF,INF,0,0,0 };
    //定义一个变量,表示当前的乘车方案
    Plan current = { vector<Train>(),0,0,0,0,0,0 };
    //定义一个变量,表示已经访问过的站点
    vector <string> visited;
    //调用一个递归函数,进行深度优先搜索,寻找最优的乘车方案
    dfs(start, endp, best, current, visited);
    //如果最优的乘车方案为空,就提示用户没有找到合适的方案
    if (best.trains.empty()) cout << "没有找到从" << start << "到" << endp << "的合适的乘车方案" << endl;
    else
    {
        //否则,输出最优的乘车方案的详细信息
        cout << "从" << start << "到" << endp << "的最优的乘车方案如下:" << endl;
        printPlan(best);
    }
}
//定义一个函数,输入模块,获取用户的输入
void input()
{
    //输出欢迎信息
    cout << "欢迎使用春运乘车方案规划系统" << endl;
    //输出站点列表
    for (int i = 0; i < stations.size(); i++) cout << stations[i] << " ";
    cout << endl;
    //获取用户的输入
    string start, endp;
    cout << "请输入起点站:" << endl;
    cin >> start;
    cout << "请输入终点站:" << endl;
    cin >> endp;
    //调用规划函数,输出结果
    plan(start, endp);
}
//定义一个函数,输出模块,输出系统的相关信息
void output()
{
    //输出系统的名称,版本,作者等信息
    cout << endl;
    cout << "\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n";
    cout << "\t\t\t\t☆===============春运乘车方案规划系统=============☆\n";
    cout << "\t\t\t\t☆~~~~~~~~~~~~~~~~~~~版本:12.0~~~~~~~~~~~~~~~~~~~☆\n";
    cout << "\t\t\t\t☆~~~~~~~~~~~~~~~~~作者:铁路规划者~~~~~~~~~~~~~~~☆\n";
    cout << "\t\t\t\t☆~~~~~~~~~~~~~~~日期:2023年12月25日~~~~~~~~~~~~~☆\n";
    cout << "\t\t\t\t☆================================================☆\n";
    cout << "\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n";
    cout << "========================================================================================================================" << endl;
}
void local_file_modify(string ID, bool add, bool modify, string insert)
{
    fstream infile;//读文件
    infile.open("d:\\out.txt", ios::in);

    fstream f;//写文件
    f.open("d:\\out.txt", ios::out | ios::app);

    //追加写入,在原来基础上加了ios::app,并且是末尾添加
    if (add)//只添加
    {
        f << endl;
        f << insert << endl;
        f.close();
        infile.close();
        return;
    }

    string s;
    vector<string>t;
    while (getline(infile, s))//读入所有数据
    {
        t.push_back(s);
    }

    string file_name = "d:\\out.txt";
    ofstream file_writer(file_name, ios_base::out);//清空文件内容

    for (int i = 0; i < t.size(); i++)//刨去删除内容,或者修改的内容
    {
        int j;
        for (j = 0; j < t[i].size(); j++)//找到第一个空格,前面的数据就是id
        {
            if (t[i][j] == ' ')
                break;
        }
        if (t[i].substr(0, j) == ID)//substr判断id是否相等,相等则过滤掉
            continue;
        else//反之将其重新读入txt
        {
            f << t[i] << endl;
        }
    }
    if (modify)
        f << insert << endl;
    infile.close();
    f.close();
}
//定义一个函数,添加线路
void addTrain()
{
    //输出提示信息
    cout << "请输入要添加的线路的信息,格式为:列车编号 起点站 终点站 出发时间 到达时间 软卧票价 硬卧票价 硬座票价 " << endl;
    cout << "(注意 出发时间和到达时间,以分钟为单位)" << endl;
    // 例如:G1 北京 上海 420 1020 933 553 0
    // 获取用户的输入
    string id, from, to;
    int depart, arrive;
    int soft, hard, seat;
    cin >> id >> from >> to >> depart >> arrive >> soft >> hard >> seat;
    //创建一个新的列车对象
    Train train = { id,from,to,depart,arrive,soft,hard,seat };
    //将新的列车对象添加到时刻表中
    timeable.push_back(train);
    // 如果起点站不在站点集合中,就添加进去
    if (find(stations.begin(), stations.end(), from) == stations.end())
    {
        stations.push_back(from);
    }
    // 如果终点站不在站点集合中,就添加进去
    if (find(stations.begin(), stations.end(), to) == stations.end())
    {
        stations.push_back(to);
    }
    // 如果起点站不在邻接表中,就添加一个空的邻接表项
    if (adj.find(from) == adj.end())
    {
        adj[from] = vector<Train>();
    }
    // 在起点站的邻接表中添加这趟列车
    adj[from].push_back(train);
    //修改文件数据
    string file = id + " " + from + " " + to_string(depart) + " " + to_string(arrive) + " " + to_string(soft) + " " + to_string(hard) + " " + to_string(seat);
    local_file_modify(id, 1, 0, file);//只加,不删,不改
    // 输出添加成功的信息
    cout << "添加成功,已添加以下线路:" << endl;
    cout << id << " " << from << " " << format(depart) << " -> " << to << " " << format(arrive) << endl;
}
//定义一个函数,修改线路
void modifyTrain()
{
    //输出提示信息
    cout << "请输入要修改的线路的列车编号:" << endl;
    //获取用户的输入
    string id;
    cin >> id;
    //在时刻表中查找对应的列车对象
    Train* train = nullptr;
    for (int i = 0; i < timeable.size(); i++)
    {
        if (timeable[i].id == id)
        {
            train = &timeable[i];
            break;
        }
    }
    //如果没有找到,就提示用户输入有误
    if (train == nullptr)
    {
        cout << "没有找到该列车编号,请重新输入" << endl;
        return;
    }
    //输出要修改的线路的原始信息
    cout << "要修改的线路的原始信息如下:" << endl;
    cout << train->id << " " << train->from << " " << format(train->depart) << " -> " << train->to << " " << format(train->arrive) << endl;
    //输出提示信息
    cout << "请输入要修改的线路的新信息,格式为:起点站 终点站 出发时间 到达时间 软卧票价 硬卧票价 硬座票价" << endl;
    cout << "(注意 出发时间和到达时间,以分钟为单位)" << endl;
    //例如:北京 上海 420 1020 933 553 0
    //获得用户的输入
    string from, to;
    int depart, arrive;
    int soft, hard, seat;
    cin >> from >> to >> depart >> arrive >> soft >> hard >> seat;
    //在起点站的邻接表中删除这趟列车
    //map <string,vector<Train>> adj; //表示站点之间的邻近表
    //adj[train->from].erase(remove(adj[train->from].begin(), adj[train->from].end(), *train), adj[train->from].end());
    //vector <Train> ::iterator it=adj[train->from].begin();
    for (auto it = adj[train->from].begin(); it != adj[train->from].end(); it++)
    {
        Train t = *it;
        if (train->id == t.id)
        {
            adj[train->from].erase(it);
            break;
        }
    }
    //修改列车对象的属性
    train->from = from;
    train->to = to;
    train->arrive = arrive;
    train->soft = soft;
    train->hard = hard;
    train->seat = seat;
    // 如果起点站不在站点集合中,就添加进去
    if (find(stations.begin(), stations.end(), from) == stations.end())
    {
        stations.push_back(from);
    }
    // 如果终点站不在站点集合中,就添加进去
    if (find(stations.begin(), stations.end(), to) == stations.end())
    {
        stations.push_back(to);
    }
    // 如果起点站不在邻接表中,就添加一个空的邻接表项
    if (adj.find(from) == adj.end())
    {
        adj[from] = vector<Train>();
    }
    // 在起点站的邻接表中添加这趟列车
    adj[from].push_back(*train);
    //修改文件
    string file = id + " " + train->from + " " + train->to + " " + to_string(train->depart) + " " + to_string(train->arrive) + " " + to_string(train->soft) + " " + to_string(train->hard) + " " + to_string(train->seat);
    local_file_modify(id, 0, 1, file);//只修改

    // 输出修改成功的信息
    //string file = id + " " + from + " " + to_string(depart) + " " + to_string(arrive) +" "+ to_string(soft) + " " + to_string(hard) + " " + to_string(seat);
    cout << "修改成功,已修改以下线路:" << endl;
    cout << train->id << " " << train->from << " " << format(train->depart) << " -> " << train->to << " " << format(train->arrive) << endl;
}
// 定义一个函数,删除线路
void deleteTrain()
{
    //输出提示信息
    cout << "请输入要删除的线路的列车编号:" << endl;
    //获取用户的输入
    string id;
    cin >> id;
    //在时刻表中查找对应的列车对象
    Train* train = nullptr;
    Train last;
    for (int i = 0; i < timeable.size(); i++)
    {
        if (timeable[i].id == id)
        {
            train = &timeable[i];
            last = timeable[i];
            break;
        }
    }
    //如果没有找到,就提示用户输入有误
    if (train == nullptr)
    {
        cout << "没有找到该列车编号,请重新输入" << endl;
        return;
    }
    //输入要删除的线路信息
    cout << "要删除的线路信息如下:" << endl;
    cout << train->id << " " << train->from << " " << format(train->depart) << " -> " << train->to << " " << format(train->arrive) << endl;
    //在时刻表中删除这趟列车
    for (auto it = timeable.begin(); it != timeable.end(); it++)
    {
        Train t = *it;
        if (train->id == t.id)
        {
            timeable.erase(it);
            break;
        }
    }
    //在起点站的邻接表中删除这趟列车
    for (auto it = adj[train->from].begin(); it != adj[train->from].end(); it++)
    {
        Train t = *it;
        if (train->id == t.id)
        {
            adj[train->from].erase(it);
            break;
        }
    }
    //删除文件里的数据
    string file = id + " " + last.from + " " + last.to + " " + to_string(last.depart) + " " + to_string(last.arrive) + " " + to_string(last.soft) + " " + to_string(last.hard) + " " + to_string(last.seat);

    local_file_modify(id, 0, 0, file);//0,0代表不加,不改,只删

    //输出删除成功的信息
    cout << "删除成功,已删除以下线路:" << endl;
    cout << last.id << " " << last.from << " " << format(last.depart) << " -> " << last.to << " " << format(last.arrive) << endl;
}
//定义一个函数,数据操纵功能模块,实现添加、修改或者删除线路、站点信息等功能
void manipulate()
{
    //输出提示信息
    cout << "请选择要进行的操作:(输入数字)" << endl;
    cout << "1. 添加线路" << endl;
    cout << "2. 修改线路" << endl;
    cout << "3. 删除线路" << endl;
    cout << "4. 返回" << endl;
    //获取用户的选择
    string shuzi;
    cin >> shuzi;
    int choice;
    if (shuzi.size() != 1) choice = 6;
    else
    {
        if (shuzi[0] >= '1' && shuzi[0] <= '4') choice = shuzi[0] - '0';
        else choice = 6;
    }
    switch (choice)
    {
    case 1://添加线路
        addTrain();
        break;
    case 2://修改线路
        modifyTrain();
        break;
    case 3://删除线路
        deleteTrain();
        break;
    case 4://返回
        return;
    default://输入错误
        cout << "输入有误,请重新输入" << endl;
        break;
    }
    cout << "--------------------------" << endl;
}


//定义一个函数,查询所有线路
void queryAll()
{
    //输出提示信息
    cout << "以下是所有的线路:" << endl;
    //遍历时刻表,输出每一趟列车的信息
    for (int i = 0; i < timeable.size(); i++)
    {
        Train train = timeable[i];
        cout << train.id << " " << train.from << " " << format(train.depart) << " -> " << train.to << " " << format(train.arrive) << endl;
    }
}
//定义一个函数,查询某个站点的所有线路
void queryStation()
{
    //输出提示信息
    cout << "请输入要查询的站点:" << endl;
    //获取用户的输入
    string station;
    cin >> station;
    //如果站点不在站点集合中,就提示用户输入有误
    if (find(stations.begin(), stations.end(), station) == stations.end())
    {
        cout << "站点不存在,请重新输入" << endl;
        return;
    }
    //如果站点在站点集合中,但是没有该站点为起点站的列车,即adj[station].size()==0
    if (adj[station].empty())
    {
        cout << "没有以该站点为起始点的列车线路" << endl;
        return;
    }
    //输出提示信息
    cout << "以下是" << station << "的所有线路" << endl;
    //在邻接表查找对应的站点,输出每一趟列车信息
    for (int i = 0; i < adj[station].size(); i++)
    {
        Train train = adj[station][i];
        cout << train.id << " " << train.from << " " << format(train.depart) << " -> " << train.to << " " << format(train.arrive) << endl;
    }
}
//定义一个函数,查询某个列车的详细信息
void queryTrain()
{
    //输出提示信息
    cout << "请输入要查询的列车编号:" << endl;
    //获取用户的输入
    string id;
    cin >> id;
    //在时刻表中查找对应的列车对象
    Train* train = nullptr;
    for (int i = 0; i < timeable.size(); i++)
    {
        if (timeable[i].id == id)
        {
            train = &timeable[i];
            break;
        }
    }
    //如果没有找到,就提示用户输入有误
    if (train == nullptr)
    {
        cout << "没有找到该列车编号,请重新输入" << endl;
        return;
    }
    //输出列车的详细信息
    cout << "以下是" << train->id << "的详细信息:" << endl;
    cout << "起点站" << train->from << endl;
    cout << "终点站" << train->to << endl;
    cout << "出发时间" << format(train->depart) << endl;
    cout << "到达时间" << format(train->arrive) << endl;
    cout << "软卧票价" << train->soft << "元" << endl;
    cout << "硬卧票价" << train->hard << "元" << endl;
    cout << "硬座票价" << train->seat << "元" << endl;
}
//定义一个函数,查询功能模块,实现查询线路的相关信息
void query()
{
    //输出提示信息
    cout << "请选择要查询的内容:(输入数字)" << endl;
    cout << "1.查询所有线路" << endl;
    cout << "2.查询某个站点的所有线路" << endl;
    cout << "3.查询某个列车的详细信息" << endl;
    cout << "4.返回" << endl;
    //获取用户的选择
    string shuzi;
    cin >> shuzi;
    int choice;
    if (shuzi.size() != 1) choice = 6;
    else
    {
        if (shuzi[0] >= '1' && shuzi[0] <= '5') choice = shuzi[0] - '0';
        else choice = 6;
    }
    //根据用户的选择,执行相应的操作
    switch (choice)
    {
    case 1://查询所有线路
        queryAll();
        break;
    case 2://查询某个站点的所有线路
        queryStation();
        break;
    case 3://查询某个列车的详细信息
        queryTrain();
        break;
    case 4://返回
        return;
    default://输入有误
        cout << "输入有误,请重新输入" << endl;
        break;
    }
    cout << "--------------------------" << endl;
}
bool cmp(Train a, Train b)
{
    return a.depart < b.depart;
}
void preprocess()
{
    //对时刻表按照出发时间进行升序排序
    sort(timeable.begin(), timeable.end(), cmp);
    //对邻接表中的每个列表也按照也按照出发时间进行升序排序
    for (auto& p : adj)
    {
        sort(p.second.begin(), p.second.end(), cmp);
    }
    cout << "预处理已完成" << endl;
    cout << "--------------------------" << endl;
}
//定义一个函数,方案规划模块,调用深度优先搜索算法,规划乘车方案
void schedule()
{
    //输出提示信息
    cout << "请选择要进行的操作:(输入数字)" << endl;
    cout << "1.规划乘车方案" << endl;
    cout << "2.返回" << endl;
    //获取用户的选择
    string shuzi;
    cin >> shuzi;
    int choice;
    if (shuzi.size() != 1) choice = 6;
    else
    {
        if (shuzi[0] >= '1' && shuzi[0] <= '2') choice = shuzi[0] - '0';
        else choice = 6;
    }
    //根据用户的选择,执行相应的操作
    switch (choice)
    {
    case 1://规划乘车方案
        input();
        break;
    case 2://返回
        return;
    default://输入错误
        cout << "输入有误,请重新输入" << endl;
        break;
    }
    cout << "--------------------------" << endl;
}
//定义一个函数,主菜单,提供用户选择不同的功能模块
void menu(int f)
{
    //输出提示信息
    if (f)//管理员的功能模块
    {
        cout << "欢迎使用管理员系统" << endl;
        cout << "请选择要使用的功能模块:(输入数字)" << endl;
        cout << "1.数据操纵功能模块" << endl;
        cout << "2.查询功能模块" << endl;
        cout << "3.预处理模块" << endl;
        cout << "4.方案规划模块" << endl;
        cout << "5.退出" << endl;
    }
    else//用户的功能模块
    {
        cout << "欢迎使用用户游客系统" << endl;
        cout << "请选择要使用的功能模块:(输入数字)" << endl;
        cout << "1.查询功能模块" << endl;
        cout << "2.预处理模块" << endl;
        cout << "3.方案规划模块" << endl;
        cout << "4.退出" << endl;
    }
    //获取用户的选择
    string shuzi;
    cin >> shuzi;
    int choice;
    if (shuzi.size() != 1) choice = 6;
    else
    {
        if (shuzi[0] >= '1' && shuzi[0] <= '5') choice = shuzi[0] - '0';
        else choice = 6;
        if (!f) choice++;
    }
    //根据用户的选择,执行相应的操作
    switch (choice)
    {
    case 1:
    {    //数据操纵功能模块
        if (!f)
            cout << "输入有误,用户无法调用此模块,请稍后登录管理员系统" << endl;
        else
            manipulate();
        break;
    }
    case 2://查询功能模块
        query();
        break;
    case 3://预处理mokuai
        preprocess();
        break;
    case 4://方案规划模块
        schedule();
        break;
    case 5://退出
        cout << "感谢使用春运乘车方案规划系统,再见!" << endl << "--------------------------" << endl;
        break;
    default://输入有误
        cout << "输入有误,请重新输入" << endl << "--------------------------" << endl;
        break;
    }
    if (choice == 5) flag = 1;
}
//定义一个登录函数用来区分管理员与用户
void login()
{
    if (!tag)
    {
        printf("\n");
        printf("\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
        printf("\t\t\t\t☆===========欢迎使用春运乘车方案规划系统=========☆\n");
        printf("\t\t\t\t☆~~~~~~~~~~~~~~~~~1.管理员登陆~~~~~~~~~~~~~~~~~~~☆\n");
        printf("\t\t\t\t☆~~~~~~~~~~~~~~~~~2.用户登录~~~~~~~~~~~~~~~~~~~~~☆\n");
        printf("\t\t\t\t☆~~~~~~~~~~~~~~~~~3.退出系统~~~~~~~~~~~~~~~~~~~~~☆\n");
        printf("\t\t\t\t☆================================================☆\n");
        printf("\t\t\t\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n");
        printf("========================================================================================================================\n");
        cout << "请输入您选择的登陆系统" << endl;
    }
    int op;
    cin >> op;
    if (op == 1)//选择了管理员系统,可以增加,修改,删除线路
    {
        cout << "请输入管理员密码" << endl;
        cout << "--------------------------" << endl;
        string manager_password;
        cin >> manager_password;
        while (manager_password != MANAGER_PASSWORD) {
            cout << "密码有误,请重新输入!!!!" << endl;
            cin >> manager_password;
        }
        while (true)
        {
            menu(1);
            if (flag) break;
        }
    }
    else if (op == 2)//选择了用户游客登录系统,不能随意修改数据
    {
        cout << "请输入用户密码" << endl;
        cout << "--------------------------" << endl;
        string user_password;
        cin >> user_password;
        while (user_password != USER_PASSWORD) {
            cout << "密码有误,请重新输入!!!!" << endl;
            cin >> user_password;
        }
        while (true)
        {
            menu(0);
            if (flag) break;
        }
    }
    else if (op == 3)
    {
        cout << "谢谢您的使用,下次再见." << endl;
        cout << "--------------------------" << endl;
        flag = 5;
        mark = 1;
    }
    else
    {
        tag = 1;
        cout << "输入有误,请重新输入" << endl;
        cout << "--------------------------" << endl;
    }
}
signed main()
{
    //初始化全局变量
    init();
    //循环显示主菜单,直到用户选择退出
    while (true)
    {
        login();
        if (flag && mark)
        {
            output();//输出系统的相关信息
            break;
        }
        flag = 0;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值