Advertisement
gertsog

y2018-4-1-C

Mar 2nd, 2020
623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.81 KB | None | 0 0
  1. #include <iterator>
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <set>
  6.  
  7. #pragma warning(disable : 4018)
  8.  
  9. #define FILL(A, c) std::generate((A).begin(), (A).end(), []() { return (c); })
  10. #define SORT(A, c) std::sort((A).begin(), (A).end(), (c))
  11. #define FIND(A, c) std::find((A).begin(), (A).end(), (c))
  12.  
  13. typedef unsigned uint;
  14. typedef std::vector<bool> bvec;
  15. typedef std::vector<unsigned> uivec;
  16. typedef std::vector<int> ivec;
  17. typedef std::pair<uint, uint> edge;
  18. typedef std::vector<ivec> matr;
  19.  
  20. struct kun
  21. {
  22.   // public 'cause i'm too lazy to make getters
  23.   matr G;
  24.   static ivec weights;
  25.   std::vector<edge> edges_list;
  26. private:
  27.   std::set<int> match_edges_;
  28.   bvec verts_list_;
  29.   static uint n, m;
  30.   ivec matching_;
  31.   bvec used_;
  32.   uint match_weight_ = 0;
  33.  
  34.   friend std::ostream & operator<<(std::ostream & os, const kun & m_m)
  35.   {
  36.     os << m_m.match_weight_ << std::endl << m_m.match_edges_.size() << std::endl;
  37.  
  38.     for (const auto a : m_m.match_edges_)
  39.       std::cout << a + 1 << " ";
  40.  
  41.     return os;
  42.   }
  43.  
  44.   bool dfs(const uint v, const bool filtered)
  45.   {
  46.     if (used_[v] || filtered && !verts_list_[v])
  47.       return false;
  48.  
  49.     used_[v] = true;
  50.  
  51.     for (const auto to : G[v])
  52.       if (matching_[to] == -1 || dfs(matching_[to], filtered))
  53.       {
  54.         matching_[to] = v;
  55.         return true;
  56.       }
  57.     return false;
  58.   }
  59.  
  60. public:
  61.   explicit kun(const uint _n = 0, const uint _m = 0) : G(_n + _m, ivec()), used_(_n + _m, false) { n = _n, m = _m; }
  62.  
  63.   kun & obtain_max_matching()
  64.   {
  65.     const auto cmp = [](const int & a, const int & b)->int { return weights[a] > weights[b]; };
  66.  
  67.     ivec order;
  68.     matching_ = ivec(n + m, -1);
  69.     verts_list_ = bvec(n + m, false);
  70.  
  71.     // left
  72.     order.resize(0);
  73.     for (uint i = 0; i < n; ++i) order.push_back(i);              // prepare order
  74.     SORT(order, cmp);                                             // sort
  75.     for (auto & us : G) SORT(us, cmp);                            // sort childs
  76.     for (const auto i : order) FILL(used_, false), dfs(i, false); // Kuhn
  77.     for (uint i = n; i < n + m; ++i)
  78.       if (matching_[i] != -1)
  79.         verts_list_[matching_[i]] = true;
  80.  
  81.     // right
  82.     FILL(matching_, -1);
  83.     order.resize(0);
  84.     for (uint i = n; i < n + m; ++i) order.push_back(i);
  85.     SORT(order, cmp);
  86.     for (auto & us : G) SORT(us, cmp);
  87.     for (const auto i : order) FILL(used_, false), dfs(i, false);
  88.     for (uint i = 0; i < n; ++i)
  89.       if (matching_[i] != -1)
  90.         verts_list_[matching_[i]] = true;
  91.  
  92.     // all
  93.     FILL(matching_, -1);
  94.     for (uint i = 0; i < n + m; ++i)
  95.       FILL(used_, false), dfs(i, true);
  96.  
  97.     // collect
  98.     match_edges_.clear();
  99.     for (int i = 0; i < n + m; ++i)
  100.       if (matching_[i] != -1)
  101.       {
  102.         const auto tmp = get_edge_index(i);
  103.         if (tmp != -1)
  104.           match_edges_.insert(tmp);
  105.       }
  106.  
  107.     match_weight_ = 0;
  108.     for (const auto & e : match_edges_)
  109.       if (e != -1)
  110.         match_weight_ += weights[edges_list[e].first] + weights[edges_list[e].second + n];
  111.  
  112.     return *this;
  113.   }
  114.  
  115.   [[nodiscard]] int get_edge_index(uint u) const
  116.   {
  117.     const edge e = edge(u, matching_[u] - n);
  118.  
  119.     for (uint i = 0; i < edges_list.size(); ++i)
  120.       if (e == edges_list[i])
  121.         return i;
  122.  
  123.     return -1;
  124.   }
  125. };
  126. ivec kun::weights;
  127. uint kun::n, kun::m;
  128.  
  129. int main()
  130. {
  131.   uint n = 0, m = 0, a = 0, b = 0, w = 0, e = 0;
  132.  
  133.   std::cin >> n >> m >> e;
  134.  
  135.   kun calculator(n, m);
  136.  
  137.   for (uint i = 0; i < n + m; i++)
  138.     std::cin >> w, kun::weights.emplace_back(w);
  139.  
  140.   while (e--)
  141.   {
  142.     std::cin >> a >> b;
  143.     calculator.edges_list.emplace_back(edge(--a, --b));
  144.     calculator.G[a].emplace_back(b + n);
  145.     calculator.G[b + n].emplace_back(a);
  146.   }
  147.  
  148.   std::cout << calculator.obtain_max_matching();
  149.  
  150.   return 0;
  151. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement