1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include <cstdio> #include <queue> #include <cstring>
inline int min(const int x, const int y) {return x < y ? x : y;} struct Node {int x, y;}; const int dx[] = {-1, 1, 0, 0}; const int dy[] = {0, 0, -1, 1}; std::queue<Node> Q; std::vector<int> G[105];
int lnk[105], x[105], y[105], dis[105][205], tp[105][105], h[105][105]; int rx[105], ry[105], n, m, k, tot; bool vis[105], mark[105][105]; bool Find(const int u) { for (int v : G[u]) if (!vis[v] && (vis[v] = true)) if (!lnk[v] || Find(lnk[v])) return lnk[v] = u, true; return false; }
void SPFA(const int sx, const int sy, const int d) { memset(mark, 0, sizeof mark); memset(tp, 0x3f, sizeof tp); tp[sx][sy] = 0; Q.push(Node{sx, sy}); while (Q.size()) { int x(Q.front().x), y(Q.front().y); Q.pop(); mark[x][y] = false; for (int k(0); k <= 3; ++ k) { int x0(x + dx[k]), y0(y + dy[k]); if (x0 < 1 || n < x0 || y0 < 1 || m < y0) continue; int ans(0), tmp((tp[x][y] & 1) ^ d); if (h[x][y] < h[x0][y0] && tmp) ans = 1; if (h[x][y] > h[x0][y0] && !tmp) ans = 1; if (tp[x][y] + ans < tp[x0][y0]) { tp[x0][y0] = tp[x][y] + ans; if (!mark[x0][y0]) Q.push(Node{x0, y0}), mark[x0][y0] = true; } } } }
bool check(const int mid) { memset(lnk, 0, sizeof lnk); int ans(0); for (int i(1); i <= 2 * k; ++ i) G[i].clear(); for (int i(1); i <= 2 * k; ++ i); for (int i(1); i <= 2 * k; ++ i) for (int j(1); j <= tot; ++ j) if (dis[i][j] <= mid) G[i].push_back(j); for (int i(1); i <= 2 * k; ++ i) memset(vis, 0, sizeof vis), ans += Find(i); return ans + mid >= 2 * k; }
int main() { int t, l(0), r; scanf("%d%d%d%d", &n, &m, &k, &t); for (int i(1); i <= 2 * k + 1; ++ i) scanf("%d%d", x + i, y + i); for (int i(1); i <= t; ++ i) { int x, y, r; scanf("%d%d%d", &x, &y, &r); while (r --) rx[++ tot] = x, ry[tot] = y; } for (int i(1); i <= n; ++ i) for (int j(1); j <= m; ++ j) scanf("%d", &h[i][j]); for (int i(1); i <= 2 * k; ++ i) { SPFA(x[i], y[i], i > k); for (int j(1); j <= tot; ++ j) dis[i][j] = tp[rx[j]][ry[j]]; } r = 2 * k; while (l < r) { int mid(l + r >> 1); if (check(mid)) r = mid; else l = mid + 1; } printf("%d", l); return 0; }
|