HDU 4845

写的时候有点痛苦,变量太多了...

不过完全独立自己写完以后确实很爽,这里将钥匙的集合看作第三个维度,看作一个扩展的图此题就可以使用BFS解决了(必定是要BFS,因为要寻找最短的路径)

这里的话,需要注意位运算的利用

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;

enum Direction{N, S, W, E};
const int maxn= 15+5;
const int maxp= 10+2;

typedef pair<int, int> P;
typedef pair<P, P> R;
int n, m, p;
int k, s;
int dr[maxn][maxn][4];
int key[maxn][maxn];
int pce[4][2]= {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
unsigned int vis[maxn][maxn][1<<maxp];

void Init()
{
	memset(dr, -1, sizeof(dr));
	memset(key, 0, sizeof(key));
}
bool InMaze(int x, int y)
{
	return x> 0 && x<= n && y> 0 && y<= m;
}
int BFS(int x, int y, int kee)
{
	int nx, ny;
	unsigned int dis;
	P tmp, tvl;
	queue<R> Q;

	memset(vis, -1, sizeof(vis));
	vis[x][y][kee]= 0;
	Q.push(R(P(x, y), P(0, kee)));
	while (Q.size()){
		tmp= Q.front().first;
		tvl= Q.front().second;
		Q.pop();
		x= tmp.first;
		y= tmp.second;
		dis= tvl.first;
		kee= tvl.second | key[x][y];
		vis[x][y][kee]= dis;
		if (n== x && m==y){
			return dis;
		}
		for (int i= 0; i< 4; ++i){
			nx= x+pce[i][0];
			ny= y+pce[i][1];	
			if (InMaze(nx, ny) && (dr[x][y][i] & kee) 
				&& vis[nx][ny][kee] > dis+1){
				Q.push(R(P(nx, ny), P(1+dis, kee)));
			}
		}		
	}

	return -1;
}
int main()
{
	while (EOF!= scanf("%d", &n)){
		int wl, x1, y1, x2, y2;
		scanf("%d %d %d", &m, &p, &k);
		Init();
		while (k--){
			scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &wl);
			if (x1> x2){
				dr[x1][y1][N]= dr[x2][y2][S]= wl ? 1<< wl : 0; 
			}
			else if (x1< x2){
				dr[x1][y1][S]= dr[x2][y2][N]= wl ? 1<< wl : 0;
			}
			else if (y1< y2){
				dr[x1][y1][E]= dr[x2][y2][W]= wl ? 1<< wl : 0;
			}
			else{
				dr[x1][y1][W]= dr[x2][y2][E]= wl ? 1<< wl : 0;
			}
		}
		scanf("%d", &s);
		while (s--){
			scanf("%d %d %d", &x1, &y1, &wl);
			key[x1][y1] |= 1<< wl;
		}
		cout<<BFS(1, 1, 1)<<endl;
	}
	return 0;
}
posted @ 2020-03-30 14:32  IdiotNe  阅读(128)  评论(0编辑  收藏  举报