Advertisement
dgc9715

Boats

Mar 31st, 2020
1,685
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.50 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #ifdef NeverBeRed
  6. #include "debug.h"
  7. #else
  8. #define debug(...) 9715
  9. #endif
  10. typedef long long ll;
  11. typedef long double ld;
  12. typedef complex<ll> point;
  13. #define F first
  14. #define S second
  15.  
  16. // max weight matching
  17. template<typename T>
  18. T hungarian(const vector<vector<T>> &a)
  19. {
  20.     int n = a.size(), m = a[0].size(), p, q; // n <= m
  21.     vector<T> fx(n, numeric_limits<T>::min()), fy(m, 0);
  22.     vector<int> x(n, -1), y(m, -1);
  23.     for (int i = 0; i < n; ++i)
  24.         for (int j = 0; j < m; ++j)
  25.             fx[i] = max(fx[i], a[i][j]);
  26.     for (int i = 0; i < n;)
  27.     {
  28.         vector<int> t(m, -1), s(n + 1, i);
  29.         for (p = q = 0; p <= q && x[i] < 0; ++p)
  30.             for (int k = s[p], j = 0; j < m && x[i] < 0; ++j)
  31.                 if (fx[k] + fy[j] == a[k][j] && t[j] < 0) // be careful with comparison on doubles
  32.                 {
  33.                     s[++q] = y[j], t[j] = k;
  34.                     if (s[q] < 0)
  35.                         for (p = j; p >= 0; j = p)
  36.                             y[j] = k = t[j], p = x[k], x[k] = j;
  37.                 }
  38.         if (x[i] < 0)
  39.         {
  40.             T d = numeric_limits<T>::max();
  41.             for (int k = 0; k <= q; ++k)
  42.                 for (int j = 0; j < m; ++j)
  43.                     if (t[j] < 0)
  44.                         d = min(d, fx[s[k]] + fy[j] - a[s[k]][j]);
  45.             for (int j = 0; j < m; ++j)
  46.                 fy[j] += (t[j] < 0 ? 0 : d);
  47.             for (int k = 0; k <= q; ++k)
  48.                 fx[s[k]] -= d;
  49.         }
  50.         else
  51.             ++i;
  52.     }
  53.     T ret = 0;
  54.     for (int i = 0; i < n; ++i)
  55.         ret += a[i][x[i]];
  56.     return ret;
  57. }
  58.  
  59. const int mov[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
  60.  
  61. int main()
  62. {
  63.     #ifdef TurnRed
  64.         //freopen("a.in", "r", stdin);
  65.         //freopen("a.out", "w", stdout);
  66.     #endif
  67.  
  68.     ios_base::sync_with_stdio(0), cin.tie(0);
  69.  
  70.     int n, m, x, y;
  71.     cin >> n >> m >> x >> y;
  72.     vector<vector<int>> a(n, vector<int>(m));
  73.     for (auto &i : a)
  74.         for (auto &j : i)
  75.             cin >> j;
  76.  
  77.     vector<int> s1(x), s2(y);
  78.     for (auto &i : s1) cin >> i, --i;
  79.     for (auto &i : s2) cin >> i, --i;
  80.  
  81.     vector<vector<ll>> c(x, vector<ll>(y));
  82.  
  83.     for (auto &p : s1)
  84.     {
  85.         vector<vector<ll>> d(n, vector<ll>(m, 1e14));
  86.         queue<pair<int, int>> q;
  87.         q.push({ 0, p });
  88.         d[0][p] = 0;
  89.         while (!q.empty())
  90.         {
  91.             int i, j;
  92.             tie(i, j) = q.front();
  93.             q.pop();
  94.             for (int k = 0; k < 4; ++k)
  95.             {
  96.                 int ni = i + mov[k][0];
  97.                 int nj = j + mov[k][1];
  98.                 if (ni >= 0 && ni < n && nj >= 0 && nj < m && d[ni][nj] > 1e5 && a[ni][nj] != 1)
  99.                 {
  100.                     d[ni][nj] = d[i][j] + 1;
  101.                     q.push({ ni, nj });
  102.                 }
  103.             }
  104.         }
  105.  
  106.         for (auto &j : s2)
  107.             c[&p-&s1[0]][&j-&s2[0]] = -d[n-1][j];
  108.     }
  109.  
  110.     ll ans = -hungarian(c);
  111.     if (ans > 1e13) ans = -1;
  112.     cout << ans << "\n";
  113.  
  114.     return 0;
  115. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement