HDU-2255.cpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <limits>
  4. #include <vector>
  5. using namespace std;
  6. int main() {
  7. ios::sync_with_stdio(false);
  8. cin.tie(nullptr);
  9. int n;
  10. while (cin >> n) {
  11. vector<vector<long long>> weight(n, vector<long long>(n));
  12. for (auto &row : weight) for (auto &x : row) cin >> x;
  13. vector<long long> lx(n), ly(n, 0), slack(n);
  14. vector<int> match_y(n, -1);
  15. for (int x = 0; x < n; ++x) lx[x] = *max_element(weight[x].begin(), weight[x].end());
  16. for (int root = 0; root < n; ++root) {
  17. fill(slack.begin(), slack.end(), numeric_limits<long long>::max() / 4);
  18. while (true) {
  19. vector<bool> seen_x(n, false), seen_y(n, false);
  20. auto augment = [&](auto &&self, int x) -> bool {
  21. seen_x[x] = true;
  22. for (int y = 0; y < n; ++y) if (!seen_y[y]) {
  23. long long gap = lx[x] + ly[y] - weight[x][y];
  24. if (gap == 0) {
  25. seen_y[y] = true;
  26. if (match_y[y] == -1 || self(self, match_y[y])) {
  27. match_y[y] = x; return true;
  28. }
  29. } else slack[y] = min(slack[y], gap);
  30. }
  31. return false;
  32. };
  33. if (augment(augment, root)) break;
  34. long long delta = numeric_limits<long long>::max() / 4;
  35. for (int y = 0; y < n; ++y) if (!seen_y[y]) delta = min(delta, slack[y]);
  36. for (int x = 0; x < n; ++x) if (seen_x[x]) lx[x] -= delta;
  37. for (int y = 0; y < n; ++y) {
  38. if (seen_y[y]) ly[y] += delta;
  39. else slack[y] -= delta;
  40. }
  41. }
  42. }
  43. long long answer = 0;
  44. for (int y = 0; y < n; ++y) answer += weight[match_y[y]][y];
  45. cout << answer << '\n';
  46. }
  47. }