Submission #837330

#TimeUsernameProblemLanguageResultExecution timeMemory
837330_martynasSoccer (JOI17_soccer)C++11
100 / 100
344 ms22660 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; const int mxh = 505; const int mxn = 1e5+5; const ll inf = 1e17; int h, w, n; ll A, B, C; ll s[mxn], t[mxn]; ll dist[mxh][mxh][5]; // 4 - with player, 0-3 - directions int closest[mxh][mxh]; int diri[4] = {0, 1, 0, -1}; int dirj[4] = {1, 0, -1, 0}; struct Info { ll d, i, j, k; bool operator<(const Info& other) const { return d > other.d; } }; bool in(int i, int j) { return i >= 0 && i < h && j >= 0 && j < w; } void bfs() { queue<pair<int, int>> q; vector<vector<bool>> visited(h, vector<bool>(w)); for(int i = 0; i < n; i++) { visited[s[i]][t[i]] = true; closest[s[i]][t[i]] = 0; q.push({s[i], t[i]}); } while(!q.empty()) { int i = q.front().first; int j = q.front().second; q.pop(); for(int d = 0; d < 4; d++) { int ni = i+diri[d], nj = j+dirj[d]; if(in(ni, nj) && !visited[ni][nj]) { closest[ni][nj] = closest[i][j]+1; visited[ni][nj] = true; q.push({ni, nj}); } } } } int main(int argc, char const *argv[]) { cin >> h >> w >> A >> B >> C; h++, w++; cin >> n; for(int i = 0; i < n; i++) cin >> s[i] >> t[i]; if(C <= A) { cout << C*(labs(s[0]-s[n-1])+labs(t[0]-t[n-1])) << "\n"; return 0; } for(int i = 0; i < h; i++) { for(int j = 0; j < w; j++) { for(int k = 0; k < 5; k++) dist[i][j][k] = inf; } } bfs(); priority_queue<Info> pq; dist[s[0]][t[0]][4] = 0; pq.push(Info{dist[s[0]][t[0]][4], s[0], t[0], 4}); while(!pq.empty()) { Info c = pq.top(); pq.pop(); if(dist[c.i][c.j][c.k] != c.d) continue; // cout << c.i << " " << c.j << " " << c.k << ": " << c.d << "\n"; if(c.k == 4) { // ball with a player // walk again for(int d = 0; d < 4; d++) { int ni = c.i+diri[d], nj = c.j+dirj[d]; if(in(ni, nj) && dist[ni][nj][4] > c.d+C) { dist[ni][nj][4] = c.d+C; // printf("push: %lld %d %d %d\n", dist[ni][nj][4], ni, nj, 4); pq.push(Info{dist[ni][nj][4], ni, nj, 4}); } } // kick the ball for(int d = 0; d < 4; d++) { int ni = c.i+diri[d], nj = c.j+dirj[d]; if(in(ni, nj) && dist[ni][nj][d] > c.d+A+B) { dist[ni][nj][d] = c.d+A+B; // printf("push: %lld %d %d %d\n", dist[ni][nj][d], ni, nj, d); pq.push(Info{dist[ni][nj][d], ni, nj, d}); } } } else { // ball w/o a player // continue flying int ni = c.i+diri[c.k], nj = c.j+dirj[c.k]; if(in(ni, nj) && dist[ni][nj][c.k] > c.d+A) { dist[ni][nj][c.k] = c.d+A; // printf("push: %lld %d %d %d\n", dist[ni][nj][c.k], ni, nj, c.k); pq.push(Info{dist[ni][nj][c.k], ni, nj, c.k}); } // find closest player to kick if(dist[c.i][c.j][4] > c.d+C*closest[c.i][c.j]) { dist[c.i][c.j][4] = c.d+C*closest[c.i][c.j]; pq.push(Info{dist[c.i][c.j][4], c.i, c.j, 4}); } } } ll ans = inf; for(int k = 0; k < 5; k++) ans = min(ans, dist[s[n-1]][t[n-1]][k]); cout << ans << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...