読者です 読者をやめる 読者になる 読者になる

AOJ0542 Authentication Level

認証レベル〜
自分にはだいぶ難しかった..
2つの事務所である認証レベルで新たに行ける部屋の数をDijkstraで求めて、事務所1でk個、事務所2でR-k個行ける時の認証レベルの最小値を更新していけばいいです

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<climits>
typedef long long ll;
using namespace std;
int field[500][500],cost[500][500];
int R,W,H,X,Y;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
const int INF  = 1000000000;

struct edge{
	int y,x,cost;
	edge(int y,int x,int cost) : y(y) , x(x) , cost(cost) {}
};
bool operator < (const edge &a,const edge &b){
	return a.cost > b.cost;
}
map<int,int> dijkstra(){
	int x,y,nx,ny,rec;
	map<int,int> foo;
	foo[0] = 0;
	priority_queue<edge> que;
	for(int i = 0; i < H; i++){
		for(int j = 0; j < W; j++){
			cost[i][j] = INT_MAX;
		}
	}
	cost[Y][X] = 1;
	que.push(edge(Y,X,1));
	while(!que.empty()){
		edge crt = que.top();
		que.pop();
		x = crt.x;
		y = crt.y;
		foo[crt.cost]++;
		if(cost[y][x] != crt.cost) continue;
		for(int i = 0; i < 4; i++){
			nx = x + dx[i];
			ny = y + dy[i];
			if(nx == -1 || ny == -1 || nx ==  W || ny == H)continue;
			rec = max(field[ny][nx], crt.cost);
			if(cost[ny][nx] > rec){
				cost[ny][nx] = rec;
				que.push(edge(ny,nx,rec));
			}
		}
	}
	return foo;
}		

int main(){
	while(scanf("%d", &R)){
		if(!R) break;
		vector<ll> a;
		vector<ll> b;
		a.push_back(0);
		b.push_back(0);
		map<int,int> f[2];
		for(int q = 0; q < 2; q++){
			scanf("%d %d %d %d", &W,&H,&X,&Y);
			X--;
			Y--;
			for(int i = 0; i < H; i++){
				for(int j = 0; j < W;j++){
					scanf("%d",&field[i][j]);
				}
			}
			f[q] = dijkstra();
		}
		map<int,int>::iterator it;
		for(it = f[0].begin(); it != f[0].end(); it++){
			for(int i = 0; i < it->second; i++){
				a.push_back(it->first);
			}
		}
		for(it = f[1].begin(); it != f[1].end(); it++){
			for(int i = 0; i < it->second; i++){
				b.push_back(it->first);
			}
		}
		 ll ans = INF;
		 for(int i = 0; i <= R; i++){
			 if (i < a.size() && R - i < b.size()) ans = min(ans,a[i]+b[R-i]);
		 }
		 cout << ans << endl;
	}
		return 0;
}