mfgnik

Untitled

Apr 23rd, 2020
470
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.45 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <string>
  5. #include <unordered_map>
  6. #include <utility>
  7. #include <vector>
  8.  
  9.  
  10. class Graph {
  11. public:
  12.     Graph() = default;
  13.     void addEdge(size_t first_vertex, size_t second_vertex) {
  14.         if (first_vertex == edges_.size()) {
  15.             edges_.emplace_back();
  16.             edges_.back().push_back(second_vertex);
  17.         } else {
  18.             edges_[first_vertex].push_back(second_vertex);
  19.         }
  20.     }
  21.  
  22.     bool TryKuhn(int vertex) {
  23.         if (used_[vertex]) {
  24.             return false;
  25.         }
  26.         used_[vertex] = true;
  27.         for (auto other_vertex : edges_[vertex]) {
  28.             if (mt_[other_vertex] == -1 || TryKuhn(mt_[other_vertex])) {
  29.                 mt_[other_vertex] = vertex;
  30.                 return true;
  31.             }
  32.         }
  33.         return false;
  34.     }
  35.  
  36.     std::vector<int> Kuhn() {
  37.         mt_.assign(second_size_, -1);
  38.         std::vector<bool> global_used(first_size_);
  39.         for (int vertex = 0; vertex < first_size_; ++vertex) {
  40.             for (auto other_vertex : edges_[vertex]) {
  41.                 if (mt_[other_vertex] == -1) {
  42.                     mt_[other_vertex] = vertex;
  43.                     global_used[vertex] = true;
  44.                     break;
  45.                 }
  46.             }
  47.         }
  48.         for (int vertex = 0; vertex < first_size_; ++vertex) {
  49.             if (global_used[vertex]) {
  50.                 continue;
  51.             }
  52.             used_.assign(first_size_, false);
  53.             TryKuhn(vertex);
  54.         }
  55.         std::vector<int> lines;
  56.         for (int index = 0; index < second_size_; ++index) {
  57.             if (mt_[index] != -1) {
  58.                 lines.push_back(index + 1);
  59.             }
  60.         }
  61.         return lines;
  62.     }
  63.  
  64.     void Reset(int first_size, int second_size) {
  65.         first_size_ = first_size;
  66.         second_size_ = second_size;
  67.     }
  68.  
  69. private:
  70.     std::vector<std::vector<int>> edges_;
  71.     std::vector<int> used_;
  72.     std::vector<int> mt_;
  73.     int first_size_;
  74.     int second_size_;
  75. };
  76.  
  77. namespace std {
  78.     template<>
  79.     struct hash<std::pair<int, int>> {
  80.         inline size_t operator()(const std::pair<int, int> &v) const {
  81.             std::hash<int> int_hasher;
  82.             return int_hasher(v.first) ^ int_hasher(v.second);
  83.         }
  84.     };
  85. }// namespace std
  86.  
  87. std::pair<int, int> NormalizePair(int first, int second) {
  88.     if (first == 0) {
  89.         return {0, 1};
  90.     }
  91.     auto divisor = std::gcd(first, second);
  92.     if (first < 0) {
  93.         divisor *= -1;
  94.     }
  95.     return {first / divisor, second / divisor};
  96. }
  97.  
  98.  
  99. int main() {
  100.     std::ios_base::sync_with_stdio(false);
  101.     std::cin.tie(nullptr);
  102.     int amount_of_tests;
  103.     std::cin >> amount_of_tests;
  104.     for (int test_number = 0; test_number < amount_of_tests; ++test_number) {
  105.         int lines_amount;
  106.         std::cin >> lines_amount;
  107.         Graph graph;
  108.         std::unordered_map<size_t, int> indexes;
  109.         std::unordered_map<std::pair<int, int>, size_t> first_points, second_points;
  110.         int first_size = 0, second_size = 0;
  111.         for (int word_number = 0; word_number < lines_amount; ++word_number) {
  112.             int first_parameter, second_parameter, third_parameter;
  113.             std::cin >> first_parameter >> second_parameter >> third_parameter;
  114.             if (second_parameter == 0 && third_parameter == 0) {
  115.                 continue;
  116.             }
  117.             auto first_pair = NormalizePair(first_parameter, second_parameter);
  118.             auto second_pair = NormalizePair(second_parameter, third_parameter);
  119.             if (first_points.count(first_pair) == 0) {
  120.                 ++first_size;
  121.                 first_points.emplace(first_pair, first_points.size());
  122.             }
  123.             if (second_points.count(second_pair) == 0) {
  124.                 ++second_size;
  125.                 indexes[second_size] = word_number;
  126.                 second_points.emplace(second_pair, second_points.size());
  127.             }
  128.             graph.addEdge(first_points[first_pair], second_points[second_pair]);
  129.         }
  130.         if (first_size == 0) {
  131.             std::cout << 1 << "\n" << 1 << "\n";
  132.             continue;
  133.         }
  134.         graph.Reset(first_size, second_size);
  135.         auto lines = graph.Kuhn();
  136.         std::cout << lines.size() << "\n";
  137.         for (auto line : lines) {
  138.             std::cout << indexes[line] + 1 << " ";
  139.         }
  140.         std::cout << "\n";
  141.     }
  142.  
  143.     return 0;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment