唯一の10種類が最短、キーを押して成形することができるか、BFSは行いますが、書き込みは今(ハングアップまたは
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <キュー> に#define PB一back 使用して 名前空間はstd; CONSTの INT MAXN = 13 。 CONSTの INT DX [] = { - 1、0、1、0 }。 const int型 DY [] = { 0、1、0、 - 1 }。 INTのN、M、P、K、S。 // INT E [MAXN] [MAXN] [4]。 int型のE [MAXN] [MAXN] [MAXN] [MAXN]。 //ベクトル<整数>キー[MAXN] [MAXN]。 int型のキー[MAXN] [MAXN]。 BOOL V [MAXN] [MAXN] [ 1 << 13 ]。 INT D [MAXN] [MAXN] [ 1 << 13 ]。 構造体ノード{ int型X、Y、キー、D。 ノード(){} ノード(INT XX、INT YY、INT K、int型のDD){ Xの = xxを、yはYY、キー= K、D = = DDと、 } ブール 演算子 <(constのノード&A)のconst { 戻り D> 広告。 } }。 // PRIORITY_QUEUE <ノード> Q。 // インラインINT HSH(int型のx、int型のY){ // INT KK = 0。 // ための式(I = 0 int型、iはキー[X]を<Y] .size(); iは++) // KK | =(1 <<キー[X] [Y] [I] -1)。 // } // 空隙をDij(){ // のmemset(D、から0x7f、はsizeof(d)参照)。 /// / INT KK = HSH(1,1)。 /// /用(INT i = 0; iは<キー[1] [1] .size(); iは++) /// / KK | =(1 <<キー[1] [1]〜[I] -1- ); // INT KK =キー[1] [1]。 // D [1] [1]〜[KK] = 0; // q.push(ノード(1,1、KK、0)); // しばらく(!q.empty()){ // INT X = q.top()X、Y = q.top()Y、K = q.top()キー、。。。q.pop(); // もし(V [X] [Y] [K])続けます。 // V [X] [Y] [K] = 1。 // ため(INT i = 0; iは4 '、iは++){ // INT XX = X + DX [i]は、YY = Y +のDYの【をI]。 // IF(E [X] [Y] [XX] [YY] == - 1)続けます。 // (XX <1 || XX> N || YY <1 || YY> m)が続けば、 // IF(E [X] [Y] [XX] [YY] &&(K&(1 << E [X] [Y] [XX] [YY] -1))!)続けます。 // int型KK = K; /// /用(INT J = 0; J <キー[XX] [YY] .size(); J ++) /// / KK | =(1 <<キー[XX] [YY] [J] -1- ); // KK | =キー[XX] [YY]。 // IF(D [XX] [YY] [KK]> D [X] [Y] [K] +1){ // D [XX] [YY] [KK]> D [X] [Y] [K] +1; // q.push(ノード(XX、YY、KK、D [XX] [YY] [KK]))。 // } // } // } // } キュー<ノード> Q。 INT BFS(){ q.push(ノード(1、1、キー[ 1 ] [ 1 ]、0 )); V [ 1 ] [ 1 ] [キー[ 1 ] [ 1 ] = 1 。 しばらく(! q.empty()){ ノードトン = q.front(); q.pop()。 もし(TX == N && t.y == M)リターンTD。 INT X = TX、Y = TY。 以下のために(int型 i = 0 ; iは< 4 ; iは++ ){ int型 XX = X + DX [i]は、yyは= Y + 1 DY [i]は、オプト= E [X] [Y] [XX] [YY]。 もし(XX < 1 || XX> N || YY < 1 || YY> M ||(OPT &&(K&(!1 << opt- 1))))続けます。 int型 KK = t.key | キー[XX] [YY]。 もし(V [XX] [YY] [KK])続けます。 q.push(ノード(XX、YY、KK、TD + 1))、V [XX] [YY] [KK] = 1 。 } } リターン - 1 。 } int型のmain(){ scanf関数(" %D%D%D "、&N、&M、&P); scanf関数(" %のD "、&K)。 用(int型 i = 1 ; iが= Kを<I ++は、X1、Y1、X2、Y2、G、P {) のscanf(" %D%D%D%D%D "、&X1、&Y1、&X2、およびY2、 &G)。 // もし(×1 ==×2)、P =(Y1-Y2 == 1の3:1); // IF(Y1の== Y2)P =(X1-X2 == 1 0:4)。 // E [X1] [Y1] [P] = G。 // E [X2] [Y2] [4-P] = G。 E [X1] [Y1] [X2] [Y2] = G。 E [X2] [Y2] [X1] [Y1] = G。 } のscanf(" %dの"、&S)。 以下のために(int型 i = 1 ; iが= Sを<I ++は、X、Y、Q {) のscanf(" %D%D%D "、およびX&Y、&Q)は、 // キー[X] [Y] .pb(Q)。 キー[X] [Y] | =(1 << Q)。 } // をDij(); // int型ANS = 0x7f7f7f7f。 // ため(INT i = 0; i)は=(1つの<< P <; iは++)ANS =分(ANS、D [n]は[M] [I])。 // もし(!ANS = 0x7f7f7f7f)のprintf( "%d個"、ANS)。 // 他のprintf( " - 1"); printf(" %dの" 、BFS())。 }