#include #include #include #include #include #include using namespace std; int parseID(string s) { return (s[0] - 'A') * ('Z' - 'A' + 1) + (s[1] - 'A'); } // Fucking hell. struct hash_pair { template size_t operator()(const pair& p) const { auto h1 = hash{}(p.first); auto h2 = hash{}(p.second); return h1 ^ (h2 << 1); } }; struct Graph { unordered_multimap conns; unordered_map rates; unordered_map, int, hash_pair> dist; }; void findLengths(Graph &g, int base) { deque frontier; frontier.push_back(base); g.dist.insert({{base, base}, 0}); while (!frontier.empty()) { // i love c++ i love c++ i love c++ int from = frontier.front(); int dist = g.dist[{base, from}]; frontier.pop_front(); auto range = g.conns.equal_range(from); for (auto it = range.first; it != range.second; it++) { int to = it->second; if (g.dist.count({base, to}) != 0) continue; g.dist.insert({{base, to}, dist + 1}); frontier.push_back(to); } } } Graph g; void rec(vector path, vector &avail, int time, int score) { cout << score << "\t" << time << "\t"; for (int n : path) cout << n << ","; cout << endl; int cur = path.back(); for (int i = 0; i < avail.size(); i++) { int n = avail[i]; if (n == 0) continue; avail[i] = 0; vector path2 = path; path2.push_back(n); int time2 = time + g.dist[{cur, n}] + 1; if (30 < time2) continue; int score2 = score + g.rates[n] * (30 - time2); rec(path2, avail, time2, score2); avail[i] = n; } } int main() { vector nonzero; for (string s; getline(cin, s); ) { auto numStart = s.find('=') + 1; auto numEnd = s.find(';', numStart) - numStart; int from = parseID(s.substr(6, 2)); int rate = stoi(s.substr(numStart, numEnd)); g.rates[from] = rate; if (rate != 0) nonzero.push_back(from); s = s.substr(s.find(' ', s.find("valve")) + 1); for (int i = 0; i + 2 <= s.size(); i += 4) { int to = parseID(s.substr(i, 2)); g.conns.insert({from, to}); } } findLengths(g, 0); for (int base : nonzero) findLengths(g, base); vector start = {0}; rec(start, nonzero, 0, 0); }