Idea: Para encontrar la distancia más corta al punto N, M, cuando hay una puerta, debe usar la llave correspondiente para abrir la puerta, luego usamos dis [i] [j] para indicar que el estado de la llave se mantuvo en la posición del número i es j La distancia más corta. De acuerdo con el número de identificación de la clave, inicializamos el estado de la Clave como Clave = 1 << id-1, podemos encontrar que cuando hay una clave en esta posición, nuestro estado cambiará state = state (original) | y luego ver si necesita ser actualizado. Dis puede obtener la ecuación de transferencia dis [i] [estado] = dis [i] [estado (original) | tecla], y luego moverse hacia arriba, abajo, izquierda y derecha. en movimiento, necesitamos juzgar si hay una puerta. Cuando hay una puerta, necesitamos Determinar si hay una llave para esta posición en el estado donde tenemos la llave en esta posición. Si la posición es W, veremos que 1 >> w-1 & 1 es 0, lo que significa que no hay llave de puerta. El mapa del problema es relativamente irregular. Primero, cambiamos la posición de cada punto x, y a un número, y luego ingresamos la posición de la pared y la puerta. Si es una pared, no importa, si es una puerta, cree un borde y use el número de la puerta. Peso, para juzgar si hay una puerta en esta posición más adelante, agreguemos todos los números de las posiciones de las puertas y paredes ingresadas en el conjunto. Más tarde, agregará bordes a toda la imagen. Si este número no se usa en este momento, significa que están entre Hay lados, cada número generalmente tiene 4 lados, así que use la matriz dir.
Código:
#pragma GCC optimize(2)#include<bits/stdc++.h>usingnamespace std;typedeflonglong ll;#define SIS std::ios::sync_with_stdio(false)#define space putchar(' ')#define enter putchar('\n')#define lson root<<1#define rson root<<1|1typedef pair<int,int> PII;typedef pair<int,PII> PIII;constint mod=1e9+7;constint N=2e5+5;constint inf=0x7f7f7f7f;intgcd(int a,int b){
return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){
return a*(b/gcd(a,b));}template<classT>voidread(T &x){
char c;bool op =0;while(c =getchar(), c <'0'|| c >'9')if(c =='-')
op =1;
x = c -'0';while(c =getchar(), c >='0'&& c <='9')
x = x *10+ c -'0';if(op)
x =-x;}template<classT>voidwrite(T x){
if(x <0)
x =-x,putchar('-');if(x >=10)write(x /10);putchar('0'+ x %10);}
ll qsm(int a,int b,int p){
ll res=1%p;while(b){
if(b&1)
res=res*a%p;
a=1ll*a*a%p;
b>>=1;}return res;}struct node
{
int to,nex,w;}edge[400];constint P=1<<10;int head[400],dis[400][P],vis[400][P];int g[400][400],key[400];int tot;int n,m,s,k;
set<PII> edges;voidadd(int u,int v,int w){
edge[tot].w=w;
edge[tot].to=v;
edge[tot].nex=head[u];
head[u]=tot++;}int dir[4][2]={
{
1,0},{
-1,0},{
0,1},{
0,-1}};voidbuild(){
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)for(int u=0;u<4;u++){
int x=i+dir[u][0],y=j+dir[u][1];if(!x||x>n||!y||y>m)continue;int a=g[i][j],b=g[x][y];if(edges.count({
a,b})==0){
add(a,b,0);add(b,a,0);}}}intbfs(){
memset(dis,inf,sizeof dis);memset(vis,0,sizeof vis);
dis[1][0]=0;
deque<PII> q;
q.push_back({
1,0});while(q.size()){
PII now=q.front();q.pop_front();int u=now.first,sta=now.second;//cout<<u<<endl;if(vis[u][sta])continue;
vis[u][sta]=1;if(u==n*m)return dis[u][sta];if(key[u]){
int state=sta|key[u];if(dis[u][state]>dis[u][sta]){
dis[u][state]=dis[u][sta];
q.push_front({
u,state});}}// cout<<"2--"<<u<<endl;for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].to,w=edge[i].w;if(w &&!(sta >> w -1&1))continue;if(dis[v][sta]>dis[u][sta]+1){
dis[v][sta]=dis[u][sta]+1;
q.push_back({
v,sta});}}}return-1;}intmain(){
cin>>n>>m>>s>>k;memset(head,-1,sizeof head);for(int i=1,t=1;i<=n;i++)for(int j=1;j<=m;j++)
g[i][j]=t++;while(k--){
int x1,x2,y1,y2,op;
cin>>x1>>y1>>x2>>y2>>op;int a=g[x1][y1],b=g[x2][y2];
edges.insert({
a,b});edges.insert({
b,a});if(op){
add(a,b,op);add(b,a,op);}}build();int rz;
cin>>rz;while(rz--){
int x,y,c;
cin>>x>>y>>c;
key[g[x][y]]|=1<<c-1;}
cout<<bfs()<<endl;return0;}