Advertisement
Guest User

Hopcroft-Karp TLE

a guest
Jan 29th, 2023
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. class Matching {
  4. public:
  5. size_t left_;
  6. size_t right_;
  7. std::vector <int> que_;
  8. std::vector <int> distance_;
  9. std::vector <int> match_left_;
  10. std::vector <int> match_right_;
  11. std::vector <std::vector <int>> adj_;
  12.  
  13. Matching(size_t left, size_t right)
  14. : left_(left),
  15. right_(right),
  16. que_(left),
  17. adj_(left),
  18. distance_(left),
  19. match_left_(left, -1),
  20. match_right_(right, -1) {
  21. }
  22.  
  23. void AddEdge(int from, int to) {
  24. adj_[from].push_back(to);
  25. }
  26.  
  27. void Bfs() {
  28. unsigned que_size_ = 0;
  29. for (size_t i = 0; i < left_; ++i) {
  30. if (match_left_[i] != -1) {
  31. distance_[i] = -1;
  32. } else {
  33. distance_[i] = 0;
  34. que_[que_size_++] = static_cast <int>(i);
  35. }
  36. }
  37.  
  38. unsigned que_ptr = 0;
  39. while (que_ptr < que_size_) {
  40. int node = que_[que_ptr++];
  41. for (const int& to : adj_[node]) {
  42. if (match_right_[to] != -1
  43. && distance_[match_right_[to]] == -1) {
  44. que_[que_size_++] = match_right_[to];
  45. distance_[match_right_[to]] = distance_[node] + 1;
  46. }
  47. }
  48. }
  49. }
  50.  
  51. bool Dfs(int node) {
  52. for (const int& to : adj_[node]) {
  53. if (match_right_[to] == -1) {
  54. match_left_[node] = to;
  55. match_right_[to] = node;
  56. return true;
  57. }
  58. }
  59.  
  60. for (const int& to : adj_[node]) {
  61. if (distance_[match_right_[to]] == distance_[node] + 1
  62. && Dfs(match_right_[to])) {
  63. match_left_[node] = to;
  64. match_right_[to] = node;
  65. return true;
  66. }
  67. }
  68.  
  69. return false;
  70. }
  71.  
  72. int HopcroftKarp() {
  73. int matching = 0;
  74. int augment = 1;
  75.  
  76. while (augment > 0) {
  77. Bfs();
  78. augment = 0;
  79. for (size_t i = 0; i < left_; ++i) {
  80. if (match_left_[i] == -1) {
  81. augment += Dfs(static_cast <int>(i));
  82. }
  83. }
  84. matching += augment;
  85. }
  86.  
  87. return matching;
  88. }
  89. };
  90.  
  91. using namespace std;
  92.  
  93. void RunCase() {
  94. int n, m, a, b;
  95. cin >> n >> m >> a >> b;
  96.  
  97. vector <vector <char>> grid(n, vector <char>(m));
  98. for (auto& row : grid) {
  99. for (auto& c : row) {
  100. cin >> c;
  101. }
  102. }
  103.  
  104. int vacant = 0;
  105. for (const auto& row : grid) {
  106. for (const auto& c : row) {
  107. vacant += (c == '*');
  108. }
  109. }
  110.  
  111. if (vacant == 0) {
  112. cout << "0\n";
  113. return;
  114. }
  115.  
  116. if (2 * b <= a) {
  117. cout << vacant * b * 2 << "\n";
  118. return;
  119. }
  120.  
  121. const int grid_size = n * m;
  122. Matching matching(grid_size / 2 + grid_size % 2, grid_size / 2);
  123.  
  124. constexpr int dx[] = {-1, 0, 0, 1};
  125. constexpr int dy[] = {0, -1, 1, 0};
  126.  
  127. vector <int> code(n * m);
  128. for (int i = 2; i < n * m; ++i) {
  129. code[i] = code[i - 2] + 1;
  130. }
  131.  
  132. for (int i = 0; i < n; ++i) {
  133. for (int j = i % 2; j < m; j += 2) {
  134. if (grid[i][j] == '.') {
  135. continue;
  136. }
  137.  
  138. for (size_t k = 0; k < 4; ++k) {
  139. int new_i = i + dx[k];
  140. int new_j = j + dy[k];
  141. if (0 <= new_i && new_i <= n - 1
  142. && 0 <= new_j && new_j <= m - 1
  143. && grid[new_i][new_j] != '.') {
  144. matching.AddEdge(code[i * m + j], code[new_i * m + new_j]);
  145. }
  146. }
  147. }
  148. }
  149.  
  150. int mat = matching.HopcroftKarp();
  151. assert(mat * 2 <= vacant);
  152. cout << mat * a + b * (vacant - 2 * mat) << "\n";
  153. }
  154.  
  155.  
  156. int main() {
  157. std::ios_base::sync_with_stdio(false);
  158. std::cin.tie(nullptr);
  159. int tt = 1;
  160. //std::cin >> tt;
  161. while (tt--) {
  162. RunCase();
  163. }
  164. return 0;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement