Advertisement
gertsog

y2018-4-1-B

Mar 2nd, 2020
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.37 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cstdlib>
  3. #include <fstream>
  4. #include <memory>
  5. #include <string>
  6. #include <vector>
  7.  
  8. #define FILL(A, c) std::generate((A).begin(), (A).end(), []() { return (c); })
  9. #define SORT(A, c) std::sort((A).begin(), (A).end(), (c))
  10. #define FIND(A, c) std::find((A).begin(), (A).end(), (c))
  11.  
  12. typedef unsigned uint;
  13. typedef std::pair<long, long> point;
  14. struct order { long time; point from, to; order(const size_t time, const point from, const point to) : time(time), from(from), to(to) {} };
  15. typedef std::vector<bool> bvec;
  16. typedef std::vector<int> ivec;
  17. typedef std::vector<ivec> matr;
  18.  
  19. class itmocar
  20. {
  21.   uint n_ = 0, taxi_cnt_ = 0;
  22.   matr city_map_;
  23.   ivec matching_;
  24.   bvec used_, mark_;
  25.   std::vector<order> orders_list_;
  26.  
  27.   bool check_same(const order &b)
  28.   {
  29.     for (const auto & a : orders_list_)
  30.       if (a.time == b.time
  31.         && a.to == b.to
  32.         && a.from == b.from)
  33.         return true;
  34.     return false;
  35.   }
  36.  
  37.   [[nodiscard]] long len(const point & a, const point & b) const { return abs(a.first - b.first) + abs(a.second - b.second); }
  38.  
  39. public:
  40.   friend std::ofstream & operator<<(std::ofstream & os, const itmocar & sys)
  41.   {
  42.     os << sys.taxi_cnt_;
  43.     return os;
  44.   }
  45.  
  46.   explicit itmocar(std::ifstream & in)
  47.   {
  48.     char redundant;
  49.     int hr, min, a, b, c, d;
  50.  
  51.     in >> n_;
  52.  
  53.     for (uint i = n_; i; i--)
  54.     {
  55.       in >> hr >> redundant >> min >> a >> b >> c >> d;
  56.       order tmp = order(hr * 60 + min, point(a, b), point(c, d));
  57.       // if (!check_same(tmp))
  58.         orders_list_.emplace_back(tmp);
  59.     }
  60.  
  61.     n_ = 2 * orders_list_.size();
  62.     city_map_ = matr(n_, ivec());
  63.     for (uint i = 0; i < orders_list_.size(); i++)
  64.       for (uint j = 0; j < orders_list_.size(); j++)
  65.       {
  66.         if (i == j)
  67.           continue;
  68.  
  69.         const auto A = orders_list_[i], B = orders_list_[j];
  70.         const auto
  71.           prev_order_endtime = A.time + len(A.from, A.to),
  72.           move_time = len(A.to, B.from),
  73.           delta = B.time - (prev_order_endtime + move_time);
  74.         if (delta >= 1)
  75.           city_map_[i].emplace_back(j + orders_list_.size());
  76.       }
  77.   }
  78.  
  79.   itmocar & obtain_max_matching()
  80.   {
  81.     // get max matching
  82.     matching_ = ivec(n_, -1);
  83.     used_ = bvec(n_, false);
  84.     for (uint i = 0; i < n_; i++)
  85.       FILL(used_, false), dfs(i);
  86.  
  87.     // cover with paths
  88.     taxi_cnt_ = n_ / 2;
  89.     mark_ = bvec(n_, false);
  90.     uint match_size_ = 0;
  91.     for (uint i = 0; i < n_; i++)
  92.       if (matching_[i] != -1)
  93.         mark_[i] = mark_[matching_[i]] = true, match_size_ += 2;
  94.  
  95.     for (uint i = 0; i < n_; i++)
  96.       taxi_cnt_ -= dfs1(i);
  97.  
  98.     return *this;
  99.   }
  100.  
  101. private:
  102.   bool dfs(const uint v)
  103.   {
  104.     if (used_[v])
  105.       return false;
  106.     used_[v] = true;
  107.  
  108.     for (auto to : city_map_[v])
  109.       if (matching_[to] == -1 || dfs(matching_[to]))
  110.       {
  111.         matching_[to] = v;
  112.         return true;
  113.       }
  114.     return false;
  115.   }
  116.  
  117.   long dfs1(const uint v)
  118.   {
  119.     if (used_[v] || !mark_[v])
  120.       return 0;
  121.     used_[v] = true;
  122.  
  123.     for (auto to : city_map_[v])
  124.       if (!used_[to] && mark_[to])
  125.         return 1 + dfs1(matching_[to]);
  126.     return 1;
  127.   }
  128. };
  129.  
  130. int main()
  131. {
  132.   std::ifstream in("taxi.in");
  133.   std::ofstream out("taxi.out");
  134.  
  135.   out << std::make_unique<itmocar>(in)->obtain_max_matching();
  136.  
  137.   out.close();
  138.   in.close();
  139.  
  140.   return 0;
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement