// vim: set ts=4 sw=4 et tw=80: #include "roadmap.h" #include #include #include #include #include using namespace std; class ConcreteRoadMap : public AbstractRoadMap { private: map< string, set > adj; /* * Adds in the map for key city1 a new set with city2 inside if there is * no prior set, otherwise it appends city2 into the existing set */ void addPair(const string& city1, const string& city2) { this->adj[city1].insert(city2); } public: ConcreteRoadMap() : adj() {}; void addRoad(const string& city1, const string& city2) override { addPair(city1, city2); addPair(city2, city1); } void addRoad(const vector& cities) override { for (size_t i = 0; i < cities.size() - 1; i++) { addRoad(cities[i], cities[i + 1]); } } void clear() override { this->adj.clear(); } int neighborCountForCity(const string& city) const override { auto i = this->adj.find(city); if (i == adj.end()) return -1; return i->second.size(); } bool hasLoop() const override { stack< std::pair > s; set discovered; bool search_comp; for (auto itr = adj.begin(); itr != adj.end(); ++itr) { search_comp = true; s.push(std::pair(itr->first, itr->first)); while (!s.empty()) { const std::pair v = s.top(); #if DEBUG std::cout << "Front is: " << v.first << " with parent " << v.second << "\n"; #endif s.pop(); if (discovered.find(v.first) == discovered.end()) { search_comp = false; discovered.insert(v.first); const auto i = this->adj.find(v.first); const auto set = i->second; for (auto j = set.begin(); j != set.end(); ++j) { if (*j != v.second) { #if DEBUG cout << "Neighbor: " << *j << " parent: " << v.first << "\n"; #endif s.push(std::pair(*j, v.first)); } } } else if (!search_comp) { // cout << v.first << " is discovered\n"; return true; } } } return false; } bool reachable(const string& c1, const string& c2) const override { if (adj.find(c1) == adj.end() || adj.find(c2) == adj.end()) { return false; } deque s; set discovered; s.push_back(c1); while (!s.empty()) { const string& v = s.front(); if (v == c2) return true; s.pop_front(); discovered.insert(v); const auto i = this->adj.find(v); const auto set = i->second; for (auto j = set.begin(); j != set.end(); ++j) { if (discovered.find(*j) == discovered.end()) { s.push_back(*j); } } } return false; } int countIslands() const override { int islands = 0; bool first; stack< std::pair > s; set discovered; for (auto itr = adj.begin(); itr != adj.end(); ++itr) { s.push(std::pair(itr->first, itr->first)); first = true; while (!s.empty()) { const std::pair& v = s.top(); s.pop(); if (discovered.find(v.first) == discovered.end()) { if (first) { islands++; } discovered.insert(v.first); const auto i = this->adj.find(v.first); const auto set = i->second; for (auto j = set.begin(); j != set.end(); ++j) { if (*j != v.second) { s.push(std::pair(*j, v.first)); } } } first = false; } } return islands; } }; AbstractRoadMap* createRoadMap() { return new ConcreteRoadMap(); }