Guest User

Recursive 10199 - Tourist Guide

a guest
Sep 22nd, 2016
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.84 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <ctime>
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <set>
  8. #include <vector>
  9. #include <sstream>
  10. #include <typeinfo>
  11. #include <list>
  12. #include <map>
  13. #include <queue>
  14. #include <stack>
  15. #include <unordered_map>
  16. #include <unordered_set>
  17. #include <numeric>
  18. #include <utility>
  19. #include <iomanip>
  20. #include <bitset>
  21. #include <fstream>
  22. #include <limits>
  23.  
  24. using namespace std;
  25.  
  26. typedef long long int64;
  27.  
  28. class CutVertexFinder {
  29.  public:
  30.   CutVertexFinder(const std::vector<std::vector<int>>& g);
  31.   std::vector<int> GetCutVertices();
  32.  
  33.  private:
  34.   std::vector<std::vector<int>> graph;
  35.   const int N;
  36.  
  37.   int time;
  38.   std::vector<int> farthest_ancestor, entry, parent, num_children;
  39.  
  40.   void DFS(int root);
  41.   void DFSLoop();
  42.   bool IsRoot(int node) { return (parent[node] == node); }
  43. };
  44.  
  45. int main() {
  46.   ios_base::sync_with_stdio(0);
  47.   cin.tie(0);
  48.  
  49.   int N;
  50.   int case_no = 0;
  51.   cin >> N;
  52.  
  53.   while (N > 0) {
  54.     cin.ignore();
  55.     case_no++;
  56.  
  57.     unordered_map<string, int> city_index;
  58.     std::vector<string> cities(N);
  59.     for (int i = 0; i < N; ++i) {
  60.       cin >> cities[i];
  61.       city_index[cities[i]] = i;
  62.     }
  63.  
  64.     int M;
  65.     cin >> M;
  66.     cin.ignore();
  67.  
  68.     std::vector<std::vector<int>> graph(N);
  69.     for (int i = 0; i < M; ++i) {
  70.       string c1, c2;
  71.       cin >> c1 >> c2;
  72.  
  73.       int u = city_index[c1];
  74.       int v = city_index[c2];
  75.  
  76.       graph[u].emplace_back(v);
  77.       graph[v].emplace_back(u);
  78.     }
  79.  
  80.     CutVertexFinder f(graph);
  81.     std::vector<string> camera_cities;
  82.     for (auto&& vertex : f.GetCutVertices()) {
  83.       camera_cities.emplace_back(cities[vertex]);
  84.     }
  85.     sort(camera_cities.begin(), camera_cities.end());
  86.  
  87.     if (case_no > 1) cout << "\n";
  88.     cout << "City map #" << case_no << ": " << camera_cities.size()
  89.          << " camera(s) found\n";
  90.     for (auto&& city : camera_cities) {
  91.       cout << city << "\n";
  92.     }
  93.  
  94.     cin >> N;
  95.   }
  96.  
  97.   return 0;
  98. }
  99.  
  100. CutVertexFinder::CutVertexFinder(const std::vector<std::vector<int>>& g)
  101.     : graph(g), N(g.size()) {
  102.   time = 0;
  103.   farthest_ancestor.resize(N, -1);
  104.   entry.resize(N, -1);
  105.   parent.resize(N, -1);
  106.   num_children.resize(N, 0);
  107. }
  108.  
  109. std::vector<int> CutVertexFinder::GetCutVertices() {
  110.   std::vector<int> cut_vertices;
  111.  
  112.   DFSLoop();
  113.  
  114.   std::vector<bool> is_cut_node(N, false);
  115.   for (int i = 0; i < N; ++i) {
  116.     if (IsRoot(i)) {
  117.       if (num_children[i] > 1) is_cut_node[i] = true;
  118.     } else {  // Non root
  119.       if (farthest_ancestor[i] == i) {
  120.         if (!IsRoot(parent[i])) {
  121.           is_cut_node[parent[i]] = true;
  122.         }
  123.         if (num_children[i]) {
  124.           is_cut_node[i] = true;
  125.         }
  126.       } else if (farthest_ancestor[i] == parent[i]) {
  127.         if (!IsRoot(parent[i])) {
  128.           is_cut_node[parent[i]] = true;
  129.         }
  130.       }
  131.     }
  132.   }
  133.  
  134.   for (int i = 0; i < N; ++i) {
  135.     if (is_cut_node[i]) cut_vertices.emplace_back(i);
  136.   }
  137.   return cut_vertices;
  138. }
  139.  
  140. void CutVertexFinder::DFSLoop() {
  141.   for (int i = 0; i < N; ++i) {
  142.     if (parent[i] == -1) {
  143.       parent[i] = i;
  144.       entry[i] = time++;
  145.       farthest_ancestor[i] = i;
  146.  
  147.       DFS(i);
  148.     }
  149.   }
  150. }
  151.  
  152. void CutVertexFinder::DFS(int root) {
  153.   for (auto&& child : graph[root]) {
  154.     if (child == parent[root]) continue;
  155.  
  156.     if (parent[child] == -1) {
  157.       // Tree edge
  158.       parent[child] = root;
  159.       entry[child] = time++;
  160.       farthest_ancestor[child] = child;
  161.  
  162.       num_children[root]++;
  163.       DFS(child);
  164.  
  165.       if (entry[farthest_ancestor[child]] < entry[farthest_ancestor[root]]) {
  166.         farthest_ancestor[root] = farthest_ancestor[child];
  167.       }
  168.     } else if (entry[child] < entry[root]) {
  169.       // Back edge
  170.       if (entry[child] < entry[farthest_ancestor[root]]) {
  171.         farthest_ancestor[root] = child;
  172.       }
  173.     }
  174.   }
  175. }
Add Comment
Please, Sign In to add comment