PC/UVa:111004/10039
据说这题可以用动态规划来解,不过书上给的提示是最短路径。可以首先使用Dijkstra求出发城市到目的城市的最早到达时间,然后再将图中的边反向(即火车从到达时间开出,在开出时间到达),再次使用Dijkstra求最短路,查找回到出发城市最短时间,即最晚出发时间。
还有这题的输入不太好理解,每一趟列车是可以停靠多个车站的,而不是只有始发站和终点站。
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <iomanip>
#define MIN_DEPARTURE 0
#define MAX_ARRIVAL 2400
using namespace std;
struct Train
{
int tDeparture;
int tArrival;
size_t ID;
Train(const int tDeparture, const int tArrival, const size_t ID)
: tDeparture(tDeparture), tArrival(tArrival), ID(ID){};
};
void input(size_t &C, map<string, size_t> &mCity2ID, vector<string> &vsID2City,
vector<vector<Train>> &Graph, vector<vector<Train>> &RGraph,
int &time, string &strDeparture, string &strArrival)
{
cin >> C;
cin.get();
vsID2City.assign(C, "");
for (size_t c = 0; c < C; c++)
{
cin >> vsID2City[c];
mCity2ID.insert(pair<string, size_t>(vsID2City[c], c));
}
Graph.assign(C, vector<Train>());
RGraph.assign(C, vector<Train>());
int T = 0;
cin >> T;
for (int t = 0; t < T; t++)
{
int S = 0, tDeparture, tArrival;
size_t idDeparture, idArrival;
cin >> S;
cin >> tDeparture;
cin.get();
cin >> strDeparture;
idDeparture = mCity2ID[strDeparture];
for (int s = 1; s < S; s++)
{
cin >> tArrival;
cin.get();
cin >> strArrival;
idArrival = mCity2ID[strArrival];
Graph[idDeparture].push_back(Train(tDeparture, tArrival, idArrival));
RGraph[idArrival].push_back(Train(tDeparture, tArrival, idDeparture));
tDeparture = tArrival;
idDeparture = idArrival;
}
}
cin >> time;
cin.get();
cin >> strDeparture >> strArrival;
}
int findMinArrival(const vector<vector<Train>> &Graph,
const size_t idDeparture, const size_t idArrival, const int earliest)
{
size_t Cities = Graph.size();
vector<int> viMinArrival(Cities, MAX_ARRIVAL);
vector<int> viOpen(Cities, MAX_ARRIVAL);
size_t idCurr = idDeparture;
viMinArrival[idDeparture] = earliest;
while (1){
const vector<Train> &vecTrain = Graph[idCurr];
for (auto train : vecTrain)
{
if (viMinArrival[train.ID] == MAX_ARRIVAL &&
train.tDeparture >= viMinArrival[idCurr]){
if (train.tArrival < viOpen[train.ID]){
viOpen[train.ID] = train.tArrival;
}
}
}
int minArrival = MAX_ARRIVAL;
size_t minArrivalIdx;
for (size_t i = 0; i < viOpen.size(); i++)
{
if (viOpen[i] < minArrival){
minArrival = viOpen[i];
minArrivalIdx = i;
}
}
if (minArrival == MAX_ARRIVAL) break;
viMinArrival[minArrivalIdx] = minArrival;
viOpen[minArrivalIdx] = MAX_ARRIVAL;//将其还原
idCurr = minArrivalIdx;
if (idCurr == idArrival) break;
}
return viMinArrival[idArrival];
}
int findMaxDeparture(const vector<vector<Train>> &Graph,
const size_t idDeparture, const size_t idArrival, const int earliest)
{
size_t Cities = Graph.size();
vector<int> viMaxDeparture(Cities, MIN_DEPARTURE);
vector<int> viOpen(Cities, MIN_DEPARTURE);
size_t idCurr = idArrival;
viMaxDeparture[idArrival] = earliest;
while (1){
const vector<Train> &vecTrain = Graph[idCurr];
for (auto train : vecTrain)
{
if (viMaxDeparture[train.ID] == MIN_DEPARTURE &&
train.tArrival <= viMaxDeparture[idCurr]){
if (train.tDeparture > viOpen[train.ID]){
viOpen[train.ID] = train.tDeparture;
}
}
}
int maxDeparture = MIN_DEPARTURE;
size_t maxDepartureIdx;
for (size_t i = 0; i < viOpen.size(); i++)
{
if (viOpen[i] > maxDeparture){
maxDeparture = viOpen[i];
maxDepartureIdx = i;
}
}
if (maxDeparture == MIN_DEPARTURE) break;
viMaxDeparture[maxDepartureIdx] = maxDeparture;
viOpen[maxDepartureIdx] = MIN_DEPARTURE;//将其还原
idCurr = maxDepartureIdx;
if (idCurr == idDeparture) break;
}
return viMaxDeparture[idDeparture];
}
int main()
{
int T = 0;
cin >> T;
for (int t = 0; t < T; t++)
{
size_t C;
map<string, size_t> mCity2ID;
vector<string> vsID2City;
vector<vector<Train>> Graph, RGraph;
int earliest;
string strDeparture, strArrival;
input(C, mCity2ID, vsID2City, Graph, RGraph, earliest, strDeparture, strArrival);
cout << "Scenario " << t + 1 << endl;
int earliestArrival = findMinArrival(Graph, mCity2ID[strDeparture], mCity2ID[strArrival], earliest);
if (earliestArrival == MAX_ARRIVAL){
cout << "No connection" << endl;
}
else{
int latestDeparture = findMaxDeparture(RGraph, mCity2ID[strDeparture], mCity2ID[strArrival], earliestArrival);
cout << "Departure " << setw(4) << setfill('0') << latestDeparture << ' ' << strDeparture << endl;
cout << "Arrival " << setw(4) << setfill('0') << earliestArrival << ' ' << strArrival << endl;
}
cout << endl;
}
return 0;
}
/*
2
3
Hamburg
Frankfurt
Darmstadt
3
2
0949 Hamburg
1006 Frankfurt
2
1325 Hamburg
1550 Darmstadt
2
1205 Frankfurt
1411 Darmstadt
0800
Hamburg
Darmstadt
2
Paris
Tokyo
1
2
0100 Paris
2300 Tokyo
0800
Paris
Tokyo
*/