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;
}