记录编号 179671 评测结果 AAAAA
题目名称 [CTSC 1999] 拯救大兵瑞恩 最终得分 100
用户昵称 Gravatarlyxin65 是否通过 通过
代码语言 C++ 运行时间 0.017 s
提交时间 2015-08-17 01:17:24 内存使用 7.56 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int, int> pii;

inline int read()
{
	int x = 0; int v = 1, c = getchar();
	for(; c < '0' || c > '9'; c = getchar()) if(c == '-') v = -1;
	for(;c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
	return x * v;
}
inline void write(LL x, int ch = 10)
{
	int s[20], t = 0;
	if(x < 0) { x = -x; putchar('-'); }
	do s[t++] = x % 10; while(x /= 10);
	while(t--) putchar('0' + s[t]);
	putchar(ch);
}

const int dx[] = {1, 0, 0, -1};
const int dy[] = {0, 1, -1, 0};
const int qsize = 1024 * 16 * 16 + 5;
const int oo = 0x3f3f3f3f;

#define inc(x) ++x >= qsize ? x = 0 : 0
#define dec(x) --x < 0 ? x += qsize : 0

struct Node
{
	int z, x, y;
};

int n, m, p, k, ss, ppfish, h, r;
int Right[17][17];
int down[17][17];
int key[17][17];
Node q[qsize];
bool inq[1025][17][17];
int dis[1025][17][17];

void input()
{
	n = read(); m = read(); p = read();
	k = read(); ppfish = 1 << p;
	for(int i = 1; i <= k; ++i) {
		int a = read(), b = read();
		int c = read(), d = read();
		int g = read();
		if(a == c) {
			int e = min(b, d);
			g ? Right[a][e] |= 1 << g-1 : Right[a][e] = -1;
		} else {
			int e = min(a, c);
			g ? down[e][b] |= 1 << g-1 : down[e][b] = -1;
		}
	}
	ss = read();
	for(int i = 0; i < ss; ++i) {
		int a = read(), b = read();
		key[a][b] |= (1 << read()-1);
	}
}
inline void pb(int z, int x, int y)
{
	inq[z][x][y] = 1; q[r] = (Node){z, x, y}; inc(r);
}
inline void pf(int z, int x, int y)
{
	inq[z][x][y] = 1; dec(h); q[h] = (Node){z, x, y};
}
inline void push(int z, int x, int y)
{
	dis[z][x][y] < dis[q[h].z][q[h].x][q[h].y] ? pf(z, x, y) : pb(z, x, y);
}
inline void pop(Node &res)
{
	res = q[h]; inc(h);
	inq[res.z][res.x][res.y] = 0;
}
void solve()
{
	memset(dis, oo, sizeof(dis));
	
	dis[0][1][1] = 0;
	pb(0, 1, 1);
	
	while(h != r) {
		Node now;
		pop(now);
		int z = now.z | key[now.x][now.y];
		int tmp = dis[now.z][now.x][now.y] + 1;
		for(int i = 0; i < 4; ++i) {
			int x = now.x + dx[i];
			int y = now.y + dy[i];
			if(x < 1 || x > n || y < 1 || y > m) continue;
			if(dis[z][x][y] <= tmp) continue;
			
			bool ok = 0;
			if(i == 0 && ~down[now.x][now.y] && (down[now.x][now.y] & z) == down[now.x][now.y]) ok = 1;
			if(i == 1 && ~Right[now.x][now.y] && (Right[now.x][now.y] & z) == Right[now.x][now.y]) ok = 1;
			if(i == 2 && ~Right[x][y] && (Right[x][y] & z) == Right[x][y]) ok = 1;
			if(i == 3 && ~down[x][y] && (down[x][y] & z) == down[x][y]) ok = 1;
			
			if(ok) {
				dis[z][x][y] = tmp;
				if(!inq[z][x][y]) push(z, x, y);
			}
		}
	}
	
	int ans = oo;
	for(int i = 0; i < ppfish; ++i)
		ans = min(ans, dis[i][n][m]);
	if(ans == oo) ans = -1;
	write(ans);
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("rescue.in", "r", stdin);
	freopen("rescue.out", "w", stdout);
#endif
	
	input();
	solve();
	
#ifndef ONLINE_JUDGE
	fclose(stdin), fclose(stdout);
#endif
	return 0;
}