Submission #433144

#TimeUsernameProblemLanguageResultExecution timeMemory
433144rqiSoccer (JOI17_soccer)C++14
100 / 100
1006 ms27576 KiB
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pi;
typedef long long ll;
typedef vector<int> vi;

#define mp make_pair
#define f first
#define s second

#define sz(x) (int)(x).size()

const ll INF = 1e18;
const int MOD = 1e9+7;

const int mx = 505;

vi dx = vi{1, 0, -1, 0};
vi dy = vi{0, 1, 0, -1};

ll walking[mx][mx];
ll kicking[mx][mx][4];

int H, W;
ll A, B, C;

int N;
pi ST[100005];

bool isGood(pi a){
	return (0 <= a.f) && (a.f <= H) && (0 <= a.s) && (a.s <= W);
}

int closest_dist[mx][mx];

void genClosestDist(){
	for(int i = 0; i <= H; i++){
		for(int j = 0; j <= W; j++){
			closest_dist[i][j] = MOD;
		}
	}
	queue<pair<int, pi>> q;
	for(int i = 1; i <= N; i++){
		closest_dist[ST[i].f][ST[i].s] = 0;
		q.push(mp(0, ST[i]));
	}
	while(sz(q)){
		pair<int, pi> a = q.front(); q.pop();
		pi cur_pos = a.s;
		int dist = a.f;
		if(closest_dist[cur_pos.f][cur_pos.s] < dist) continue;
		for(int d = 0; d < 4; d++){
			pi new_pos = mp(cur_pos.f+dx[d], cur_pos.s+dy[d]);
			if(!isGood(new_pos)) continue;
			int new_dist = dist+1;
			if(closest_dist[new_pos.f][new_pos.s] > new_dist){
				closest_dist[new_pos.f][new_pos.s] = new_dist;
				q.push(mp(new_dist, new_pos));
			}
		}
	}
}

int main(){
	cin >> H >> W;
	cin >> A >> B >> C;
	cin >> N;
	for(int i = 1; i <= N; i++){
		cin >> ST[i].f >> ST[i].s;
	}
	genClosestDist();

	for(int i = 0; i <= H; i++){
		for(int j = 0; j <= W; j++){
			for(int d = 0; d < 4; d++){
				kicking[i][j][d] = INF;
			}
			walking[i][j] = INF;
		}
	}
	
	priority_queue<pair<ll, vi>, vector<pair<ll, vi>>, greater<pair<ll, vi>>> pq;
	walking[ST[1].f][ST[1].s] = 0;
	pq.push(mp(0, vi{0, ST[1].f, ST[1].s})); //type 0 is walking, 1 is kicking

	while(sz(pq)){
		ll dist = pq.top().f;
		vi state = pq.top().s;
		pi cur_pos = mp(state[1], state[2]);
		pq.pop();
		if(state[0] == 0){ //walking
			if(walking[cur_pos.f][cur_pos.s] < dist) continue;
			for(int d = 0; d < 4; d++){
				pi new_pos = mp(cur_pos.f+dx[d], cur_pos.s+dy[d]);
				ll new_dist = dist+C;
				if(!isGood(new_pos)) continue;
				if(walking[new_pos.f][new_pos.s] <= new_dist) continue;
				walking[new_pos.f][new_pos.s] = new_dist;
				pq.push(mp(new_dist, vi{0, new_pos.f, new_pos.s}));
			}
			for(int d = 0; d < 4; d++){
				ll new_dist = dist+B;
				if(kicking[cur_pos.f][cur_pos.s][d] > new_dist){
					kicking[cur_pos.f][cur_pos.s][d] = new_dist;
					pq.push(mp(new_dist, vi{1, cur_pos.f, cur_pos.s, d}));
				}
			}
			
		}
		else{
			int cur_dir = state[3];
			if(kicking[cur_pos.f][cur_pos.s][cur_dir] < dist) continue;
			pi new_pos = mp(cur_pos.f+dx[cur_dir], cur_pos.s+dy[cur_dir]);
			if(isGood(new_pos)){
				ll new_dist = dist+A;
				if(kicking[new_pos.f][new_pos.s][cur_dir] > new_dist){
					kicking[new_pos.f][new_pos.s][cur_dir] = new_dist;
					pq.push(mp(new_dist, vi{1, new_pos.f, new_pos.s, cur_dir}));
				}	
			}
			ll new_dist = dist+C*closest_dist[cur_pos.f][cur_pos.s];
			if(walking[cur_pos.f][cur_pos.s] > new_dist){
				walking[cur_pos.f][cur_pos.s] = new_dist;
				pq.push(mp(new_dist, vi{0, cur_pos.f, cur_pos.s}));
			}
		}
	}
	cout << walking[ST[N].f][ST[N].s] << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...