转化为图论问题
对于每个交叉点(X,Y)抽象成节点。与它相邻的四个点中,可以直接连线的边权为0,否则边权为1。
用死了的SPFA解决图论问题。
#include <cstring> #include <cstdio> #define GC getchar() #define Clean(X,K) memset(X,K,sizeof(X)) #define re register #define Hash(X,Y) ((X)*(M+1)+(Y)) using namespace std ; int Qread () { int X = 0 ; char C = GC ; while (C > '9' || C < '0') C = GC ; while (C >='0' && C <='9') { X = X * 10 + C - '0' ; C = GC ; } return X ; } const int Maxn = 505 , INF = 1061109567; int Times , N , M , Head[Maxn * Maxn] , En = 0 , Q[Maxn * Maxn] , Mdis[Maxn * Maxn], Vis[Maxn * Maxn]; struct Edge { int From , Goto , NextEdge , Len ; }; Edge E[Maxn * Maxn * 4] ; void Adg (int X , int Y ,int L) { E[++En].From = X ; E[En].Goto = Y ; E[En].Len = L ; E[En].NextEdge = Head[X] ; Head[X] = En ; } int SPFA () { re int H = 1 , T = 1 ; Clean(Vis , 0) , Clean(Mdis , 0x3f) ; const int St = Hash(0 , 0) , Top = (N + 1) * (M + 1); if (++T > Top) T = 0 ; Q[T] = St , Mdis[St] = 0 , Vis[St] = 1 ; while (H != T) { if (++ H > Top) H = 0 ; const int Now = Q[H] ; Vis[Now] = 0 ; for (re int i = Head[Now ] ; i ; i = E[i].NextEdge ) { int Dis = Mdis[Now] + E[i].Len ; if (Dis < Mdis[E[i].Goto ]) { Mdis[E[i].Goto ] = Dis ; if (!Vis[E[i].Goto ]) { Vis[E[i].Goto ] = 1 ; if (++ T > Top) T = 0 ; Q[T] = E[i].Goto ; } } } } return Mdis[Hash(N , M)] ; } int main () { //freopen ("P2243.in" , "r" , stdin) ; Times = Qread () ; while (Times -- ) { N = Qread () , M = Qread () ; Clean (Head , 0 ) , En = 0 ; for (re int i = 0 ; i < N ; ++ i) { for (re int j = 0 ; j < M; ++ j) { char C = GC ; while (C !='\' && C !='/') C = GC ; if (C == '/') { Adg (Hash(i + 1 , j + 1) , Hash (i , j) , 1) ; Adg (Hash (i , j) ,Hash(i + 1 , j + 1) , 1) ; Adg (Hash(i + 1 , j) , Hash (i , j + 1) , 0) ; Adg (Hash (i , j + 1) ,Hash(i + 1 , j) , 0) ; } else if (C == '\') { Adg (Hash(i + 1 , j + 1) , Hash (i , j) , 0) ; Adg (Hash (i , j) ,Hash(i + 1 , j + 1) , 0) ; Adg (Hash(i + 1 , j) , Hash (i , j + 1) , 1) ; Adg (Hash (i , j + 1) ,Hash(i + 1 , j) , 1) ; } } } int Ans = SPFA() ; if (Ans < INF)printf ("%d " , Ans) ; else printf ("NO SOLUTION ") ; } fclose (stdin) , fclose (stdout) ; return 0 ; }