Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <iostream>
- #include <queue>
- #include <string>
- #include <map>
- #include <sstream>
- #include <vector>
- #include <set>
- #include <bitset>
- #include <limits>
- #define C 1001
- using namespace std;
- using smart = pair<pair<int, int>, pair<bitset<C>, string>>; // (nr of colours, nr of nodes, mask of nodes, node)
- namespace std {
- template<> struct greater<smart>: binary_function<smart, smart, bool> {
- bool operator()(const smart& t1, const smart& t2) {
- if (t1.second.first.count() != t2.second.first.count())
- return t1.second.first.count() < t2.second.first.count();
- else return t1.first.second < t2.first.second;
- }
- };
- bool operator<(const bitset<C>& a, const bitset<C>& b) {
- return a.count() < b.count();
- }
- };
- constexpr auto Inf = numeric_limits<int>::max();
- ifstream fin("commando.in");
- ofstream fout("commando.out");
- int n;
- string country, color, source, destination, text;
- map<string, vector<string>> Graph;
- map<string, string> CForC, Parent; // country => color
- set<string> Colors, Countries;
- map<string, int> ColVal;
- priority_queue<smart, vector<smart>, greater<>> PQ;
- map<string, pair<pair<int, int>, bitset<C>>> Dist;
- void Dijkstra(const string& src) {
- bitset<C> mask; mask[ColVal[CForC[src]]] = true;
- Dist[src] = make_pair(make_pair(1, 1), mask);
- Parent[src] = "";
- PQ.push(make_pair(make_pair(Dist[src].first.first, 1), make_pair(Dist[src].second, src)));
- while (!PQ.empty()) {
- int curr_dist = PQ.top().first.first, curr_len = PQ.top().first.second;
- bitset<C> curr_mask = PQ.top().second.first;
- string curr_node = PQ.top().second.second;
- PQ.pop();
- if (curr_dist != Dist[curr_node].first.first) continue;
- for (const auto& neigh: Graph[curr_node]) {
- bitset<C> new_mask = curr_mask; new_mask[ColVal[CForC[neigh]]] = true;
- if (new_mask.count() < Dist[neigh].second.count()) {
- Dist[neigh] = make_pair(make_pair(new_mask.count(), curr_len + 1), new_mask);
- PQ.push(make_pair(make_pair(Dist[neigh].first.first, curr_len + 1), make_pair(new_mask, neigh)));
- Parent[neigh] = curr_node;
- } else if (new_mask.count() == Dist[neigh].second.count() && curr_len + 1 < Dist[neigh].first.second) {
- Dist[neigh].first.second = curr_len + 1;
- PQ.push(make_pair(make_pair(Dist[neigh].first.first, curr_len + 1), make_pair(new_mask, neigh)));
- Parent[neigh] = curr_node;
- }
- }
- }
- }
- void print_chain(const string& curr) {
- if (!Parent[curr].empty())
- print_chain(Parent[curr]);
- fout << curr << "\n";
- }
- int main() {
- fin >> n; fin.get();
- for (int i = 1; i <= n; ++i) {
- getline(fin, text);
- istringstream buffer(text); buffer >> country >> color;
- CForC[country] = color;
- Colors.insert(color);
- Countries.insert(country);
- // cout << country << " " << color << "\n";
- // istringstream buffer(neighs);
- for (string word; buffer >> word;)
- Graph[country].emplace_back(word);
- }
- fin >> source >> destination;
- int i = 0;
- for (const auto& col: Colors)
- ColVal[col] = i++;
- for (const auto& ctr: Countries) {
- bitset<C> mask; mask.set();
- Dist[ctr] = make_pair(make_pair(Inf, Inf), mask);
- // cout << ctr << " " << ColVal[CForC[ctr]] << " " << mask << "\n";
- }
- Dijkstra(source);
- if (Dist[destination].first.first != Inf) {
- fout << Dist[destination].first.first << "\n";
- print_chain(destination);
- }
- else fout << "No solution!";
- fin.close(), fout.close();
- return 0;
- }
Add Comment
Please, Sign In to add comment