题目
Dongfang, A hardworking student, last week, he made the software named Query bus route system in WuHan, but he met a very intractability
problem At first, he tried to solve it by algorithm he had learned last summer, but it’s not appropriate for the MIS (Management
Information System). However, the function of the system has declined a lot if he used the database initial function. Now, you are
an excellent programmer, it is your task to help DongFang to improve the function of the software.
Assuming that there are n stations, whose names are the first n letters of the set{A, B, C, ? , Z, a, b, c, ?, z}. And in daily life,
to pay less fee, we often choose a bus route which contains D (1<=D<=4) buses at the most.
输入格式
An integer T (0 < T < 20) at the first line of the file represents the number of cases. In each case, it begins with three integers m(1<=m<=50),
n(2<=n<=52), D, representing that there is m buses, n stations and the maximum number of buses that a route can contains. Then m lines,
each line begins with two integers k(1<=k<=m) and l, followed by l letters; each letter means the bus k can pass this station.
In the last line, there are two letters x and y, denoting the starting station and the destination.
输出格式
Each case begins with (case i:),?i? is counted from 1,and each case ends with ?There are P routes in total!?, P is the number of
total routes from starting station to end station.
All of the P routes should be output in the following rules. First, the routes should be ordered by the number of stations. Second, if number of buses in two routes is the same, you should output the routes in the lexical order. Third, if two route?s stations are the same, the route whose first bus number is smaller should be output before the other one, if it is also the same, then see the next bus number??
The route?s first station must be the starting one, and the last station must be the end station. And the stations of the route should be different from each other.
The format of the route should as follows: A 1 B 2 C It means from starting station A, you take bus 1, on arriving at the station B, you take the bus 2, finally arrive at the destination C. There is a blank line between two neighboring case, in each case, each route should be output in separated line.
样例输入
1
3 3 4
1 2 A B
2 3 B A C
3 1 A
A C
样例输出
case 1:
A 2 C
A 1 B 2 C
A 2 B 2 C
There are 3 routes in total!
解析
注意两个case输出之间有个空行。。。我就是忘了这个一直没提交通过😅
简单的回溯法,即可解决,注意数据结构的设计,我这边是把车站作为节点,以公交车号和下一站作为边的信息 来构图。理解题意的时候,注意一个巴士能经过的站都能两两直达就行了。
代码
#include<iostream>
#include<vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
int m, n, D;
char start, terminal;
void backtrack(vector<vector<pair<int, char>>>& result, vector<pair<int, char>>& route, unordered_map<char, vector<pair<int, char>>>& stations, char curStation) {
if (route.size() > D) {
return;
}
if (curStation == terminal) {
result.push_back(route);
return;
} else {
for (auto &next : stations[curStation]) {
bool flag = false;
for (auto &sta : route) { // station should be different
if (sta.second == next.second) {
flag = true;
break;
}
}
if (flag) {
continue;
}
if (next.second == start) {
continue;
}
route.emplace_back(next.first, next.second);
backtrack(result, route, stations, next.second);
route.pop_back();
}
}
}
int main() {
int t, caseNum = 0;
cin >> t;
while (caseNum++ < t) {
cin >> m >> n >> D; // m bus, n stations, maximum D station each route contains
// 临接表图
unordered_map<char, vector<pair<int, char>>> stations; //
int busNum, staNum;
for (int i = 0; i < m; ++i) {
cin >> busNum >> staNum;
vector<char> staPass(staNum);
for (int j = 0; j < staNum; ++j) {
cin >> staPass[j];
}
// 两两直达
for (int j = 0; j < staNum - 1; ++j) {
for (int k = j+1; k < staNum; ++k) {
stations[staPass[j]].push_back(make_pair(busNum, staPass[k]));
stations[staPass[k]].push_back(make_pair(busNum, staPass[j]));
}
}
}
cin >> start >> terminal;
vector<pair<int, char>> route;
vector<vector<pair<int, char>>> result;
backtrack(result, route, stations, start);
std::sort(result.begin(), result.end(), [](vector<pair<int, char>>& r1, vector<pair<int, char>>& r2){
if (r1.size() < r2.size()) {
return true;
} else if (r1.size() > r2.size()){
return false;
} else { // 经过的车站数相等
for (int i = 0; i < r1.size(); ++i) { // 车站字母顺序
if (r1[i].second != r2[i].second) {
return r1[i].second < r2[i].second;
}
}
for (int i = 0; i < r1.size(); ++i) { // 公交车顺序
if (r1[i].first != r2[i].first) {
return r1[i].first < r2[i].first;
}
}
return true;
}
});
if (caseNum != 1) {
cout << endl;
}
cout << "case " << caseNum << ":\n";
for(auto& ro : result) {
cout << start;
for (auto& sta : ro) {
cout << " " << sta.first << " " << sta.second;
}
cout << endl;
}
cout << "There are " << result.size() << " routes in total!" << endl;
}
return 0;
}