Advertisement
gertsog

y2018-4-1-D

Mar 2nd, 2020
883
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.69 KB | None | 0 0
  1. #include <vector>
  2. #include <memory>
  3. #include <fstream>
  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.  
  11. typedef unsigned uint;
  12. typedef std::vector<bool> bvec;
  13. typedef std::vector<unsigned> uivec;
  14. typedef std::vector<int> ivec;
  15. typedef std::pair<uint, uint> edge;
  16. typedef std::vector<ivec> matr;
  17.  
  18. struct guests
  19. {
  20.   size_t amt;
  21.   std::set<int> girls, boys;
  22. };
  23.  
  24. std::ostream & operator<<(std::ostream & os, const std::set<int> & v)
  25. {
  26.   for (const auto & a : v)
  27.     os << a << " ";
  28.  
  29.   return os;
  30. }
  31.  
  32. struct kun
  33. {
  34.   matr G, G1;
  35. private:
  36.   guests my_guests_ = { 0 };
  37.   static uint n_, m_;
  38.   ivec matching_;
  39.   bvec used_, mark_;
  40.  
  41. public:
  42.   explicit kun(const uint n = 0, const uint m = 0) :
  43.   G(n + m, ivec()), G1(n + m, ivec())
  44.   {
  45.     n_ = n, m_ = m;
  46.   }
  47.  
  48.   friend std::ostream & operator<<(std::ostream & os, const kun & m_m)
  49.   {
  50.     os << std::endl << m_m.my_guests_.amt << std::endl <<
  51.       m_m.my_guests_.boys.size() << " " << m_m.my_guests_.girls.size() << std::endl <<
  52.       m_m.my_guests_.boys << std::endl << m_m.my_guests_.girls;
  53.  
  54.     return os;
  55.   }
  56.  
  57.   void build_g1()
  58.   {
  59.     for (int i = 0; i < n_; i++)
  60.     {
  61.       for (int j = n_; j < n_ + m_; j++)
  62.         if ((std::find(G[i].begin(), G[i].end(), j) == G[i].end())
  63.          && (std::find(G[j].begin(), G[j].end(), i) == G[j].end()))
  64.           G1[i].push_back(j);
  65.     }
  66.  
  67.     for (int i = n_; i < n_ + m_; i++)
  68.     {
  69.       for (int j = 0; j < n_; j++)
  70.         if ((std::find(G[i].begin(), G[i].end(), j) == G[i].end())
  71.           && (std::find(G[j].begin(), G[j].end(), i) == G[j].end()))
  72.           G1[i].push_back(j);
  73.     }
  74.   }
  75.  
  76.   kun & obtain_max_matching()
  77.   {
  78.     // 1
  79.     build_g1();
  80.  
  81.     // 2
  82.     matching_ = ivec(n_ + m_, -1);
  83.     used_.resize(n_ + m_);
  84.     mark_ = bvec(n_ + m_, false);
  85.     for (uint i = 0; i < n_ + m_; ++i)
  86.       FILL(used_, false), dfs(i);
  87.  
  88.     // 3
  89.     FILL(used_, false);
  90.     for (uint i = 0; i < n_; ++i)
  91.       if (!mark_[i]) dfs1(i);
  92.  
  93.     // 4
  94.     for (uint i = 0; i < n_; i++)
  95.       if (used_[i])
  96.         my_guests_.girls.insert(i + 1);
  97.     for (uint i = n_; i < n_ + m_; i++)
  98.       if (!used_[i])
  99.         my_guests_.boys.insert(i - n_ + 1);
  100.     my_guests_.amt = my_guests_.boys.size() + my_guests_.girls.size();
  101.  
  102.     return *this;
  103.   }
  104. private:
  105.   bool dfs(const uint v)
  106.   {
  107.     if (used_[v])
  108.       return false;
  109.  
  110.     used_[v] = true;
  111.  
  112.     for (const auto to : G1[v])
  113.       if (matching_[to] == -1 || dfs(matching_[to]))
  114.       {
  115.         matching_[to] = v;
  116.         return mark_[v] = mark_[to] = true;
  117.       }
  118.     return false;
  119.   }
  120.  
  121.   void dfs1(const uint v)
  122.   {
  123.     if (used_[v])
  124.       return;
  125.  
  126.     used_[v] = true;
  127.  
  128.     for (const auto to : G1[v])
  129.     {
  130.       if (v >= n_ && (matching_[to] == v || matching_[v] == to))
  131.         dfs(to);
  132.       else if (v < n_ && (matching_[to] != v && matching_[v] != to))
  133.         dfs(to);
  134.     }
  135.   }
  136. };
  137.  
  138. uint kun::n_, kun::m_;
  139.  
  140. int main()
  141. {
  142.   uint k = 0, n = 0, m = 0, a = 0, b = 0, w = 0;
  143.   std::ifstream in("birthday.in");
  144.   std::ofstream out("birthday.out");
  145.  
  146.   in >> k;
  147.  
  148.   while (k--)
  149.   {
  150.     in >> m >> n;
  151.  
  152.     kun calculator(n, m);
  153.  
  154.     for (uint i = 0; i < m; i++)
  155.     {
  156.     again:
  157.       in >> a;
  158.       if (a == 0)
  159.         continue;
  160.       calculator.G[i + n].emplace_back(a - 1);
  161.       // calculator.G[a - 1].emplace_back(i + n);
  162.       goto again;
  163.     }
  164.  
  165.     if (m == 0 && n == 0)
  166.       out << 0 << std::endl << 0 << " " << 0 << std::endl << std::endl;
  167.     else
  168.       out << calculator.obtain_max_matching() << std::endl << std::endl;
  169.   }
  170.  
  171.   in.close(), out.close();
  172.  
  173.   return 0;
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement