|
| 1 | +/* |
| 2 | + * It's never optimal for someone to touch the ball twice. |
| 3 | + * |
| 4 | + * We can solve with dijkstra's, where our state is |
| 5 | + * |
| 6 | + * dist(i, j, k): min cost to get the ball to (i,j) where: |
| 7 | + * - if 0 <= k <= 3, k represents the direction the ball is currently traveling |
| 8 | + * (the ball is is being kicked) |
| 9 | + * - if k = 4, the ball is no longer traveling and is under the posession of a player |
| 10 | + * |
| 11 | + * We can use multi source BFS to find the min dist between every grid cell and the closest |
| 12 | + * player. Then, to transition to k = 4, we can just move the closest player to the |
| 13 | + * location of the ball. |
| 14 | + */ |
| 15 | + |
| 16 | +#include <bits/stdc++.h> |
| 17 | + |
| 18 | +using namespace std; |
| 19 | + |
| 20 | +using ll = long long; |
| 21 | +#define ii pair<int, int> |
| 22 | +#define f first |
| 23 | +#define s second |
| 24 | +#define pb push_back |
| 25 | +#define mp make_pair |
| 26 | +#define all(x) x.begin(), x.end() |
| 27 | +#define sz(x) (int)x.size() |
| 28 | +#define F0R(i, n) for (int i = 0; i < n; i++) |
| 29 | +#define FOR(i, a, b) for (int i = a; i < b; i++) |
| 30 | +#define inf 1000000010 |
| 31 | + |
| 32 | +int h, w; |
| 33 | +// min dist to get a player to (i, j) |
| 34 | +ll getPlayer[501][501]; |
| 35 | +// min cost to get ball to (i, j) |
| 36 | +// {0-3}: direction the ball is currently traveling (kicked) |
| 37 | +// 4: The ball has landed and a person is currently holding it |
| 38 | +ll dist[501][501][5]; |
| 39 | +ll a, b, c; |
| 40 | + |
| 41 | +bool g(ii x) { |
| 42 | + return x.f >= 0 && x.f <= h && x.s >= 0 && x.s <= w; |
| 43 | +} |
| 44 | + |
| 45 | +int main() { |
| 46 | + cin.tie(0)->sync_with_stdio(0); |
| 47 | + |
| 48 | + cin >> h >> w; |
| 49 | + F0R(i, h+1) F0R(j, w+1) getPlayer[i][j] = 1e18; |
| 50 | + F0R(i, h+1) F0R(j, w+1) F0R(k, 5) dist[i][j][k] = 1e18; |
| 51 | + cin >> a >> b >> c; |
| 52 | + int n; cin >> n; |
| 53 | + queue<ii> q; |
| 54 | + ii first; |
| 55 | + F0R(i, n-1) { |
| 56 | + int x, y; cin >> x >> y; q.push(mp(x, y)); |
| 57 | + if (i == 0) first = mp(x,y); |
| 58 | + getPlayer[x][y] = 0; |
| 59 | + } |
| 60 | + int dx[4]{-1,0,1,0}; |
| 61 | + int dy[4]{0,-1,0,1}; |
| 62 | + while (!q.empty()) { |
| 63 | + ii u = q.front(); q.pop(); |
| 64 | + F0R(i, 4) { |
| 65 | + ii v = mp(u.f+dx[i], u.s+dy[i]); |
| 66 | + if (g(v) && getPlayer[v.f][v.s] == 1e18) { |
| 67 | + getPlayer[v.f][v.s] = getPlayer[u.f][u.s]+1; |
| 68 | + q.push(v); |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + ii dest; cin >> dest.f >> dest.s; |
| 73 | + |
| 74 | + priority_queue<pair<ll, pair<ii, int>>, vector<pair<ll, pair<ii, int>>>, greater<pair<ll, pair<ii, int>>>> pq; |
| 75 | + pq.push(mp(0, mp(first, 4))); |
| 76 | + dist[first.f][first.s][4] = 0; |
| 77 | + while (!pq.empty()) { |
| 78 | + pair<ll, pair<ii, int>> top = pq.top(); pq.pop(); |
| 79 | + ll d = top.f; |
| 80 | + ii u = top.s.f; |
| 81 | + int dir = top.s.s; |
| 82 | + if (dist[u.f][u.s][dir] != d) continue; |
| 83 | + |
| 84 | + if (dir == 4) { |
| 85 | + // choose a direction and kick it |
| 86 | + F0R(i, 4) { |
| 87 | + ii v = u; |
| 88 | + if (g(v) && dist[v.f][v.s][i] > d+b) { |
| 89 | + dist[v.f][v.s][i] = d+b; |
| 90 | + pq.push(mp(d+b, mp(v, i))); |
| 91 | + } |
| 92 | + } |
| 93 | + // or, choose a direction and move |
| 94 | + F0R(i, 4) { |
| 95 | + ii v = mp(u.f+dx[i], u.s+dy[i]); |
| 96 | + if (g(v) && dist[v.f][v.s][4] > d+c) { |
| 97 | + dist[v.f][v.s][4] = d+c; |
| 98 | + pq.push(mp(d+c, mp(v, 4))); |
| 99 | + } |
| 100 | + } |
| 101 | + } else { |
| 102 | + // keep kicking it |
| 103 | + ii v = mp(u.f+dx[dir], u.s+dy[dir]); |
| 104 | + if (g(v) && dist[v.f][v.s][dir] > d+a) { |
| 105 | + dist[v.f][v.s][dir] = d+a; |
| 106 | + pq.push(mp(d+a, mp(v, dir))); |
| 107 | + } |
| 108 | + // stop, get somebody to pick it up |
| 109 | + if (dist[u.f][u.s][4] > d+getPlayer[u.f][u.s]*c) { |
| 110 | + dist[u.f][u.s][4] = d+getPlayer[u.f][u.s]*c; |
| 111 | + pq.push(mp(d+getPlayer[u.f][u.s]*c, mp(u, 4))); |
| 112 | + } |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + ll ans = dist[dest.f][dest.s][4]; |
| 117 | + F0R(i, 4) ans = min(ans, dist[dest.f][dest.s][i]); |
| 118 | + cout << ans << endl; |
| 119 | + |
| 120 | + return 0; |
| 121 | +} |
0 commit comments