每个方格的四个角看成是节点 如果节点与节点之间有斜线链接
就把两个节点间的权值设为0 否则设为1 (看成是需要转一次) 这样
就得到一张边权为1或0的无向图 使用bfs+deque 在每个节点上沿
分支扩展时 如果时权值为0的边从队头入队 如果是权值为1的边从
队尾入队


#include<bits/stdc++.h>
using namespace std;

typedef pair< int, int > PII;
const int N = 510;
char g[N][N];
int n, m;
int dist[N][N];
int dx[4] = {-1, 1, 1, -1};
int dy[4] = {-1, -1, 1, 1}; //dx dy 是节点往左上 右上 左下 右下 的坐标偏移量
int ix[4] = {-1, 0, 0, -1}; //ix iy 是节点的左上 上 左 节点本身坐标 代表方格中电线的摆放位置
int iy[4] = {-1, -1, 0, 0};
char str[] = "\\/\\/";
bool st[N][N];

int bfs()
{
    memset( dist, 0x3f, sizeof dist );
    dist[0][0] = 0;

    deque< PII > q;
    q.push_front( {0, 0} );

    while( q.size() )
    {
        PII t = q.front();
        q.pop_front();

        int x = t.first, y = t.second;

        if( st[x][y] )
            continue;
        st[x][y] = true;

        for( int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            int j = x + ix[i], k = y + iy[i];

            if( a >= 0 && a <= n && b >= 0 && b <= m )
            {
                int w = 0;
                if( g[j][k] != str[i] )
                    w = 1;

                if( dist[a][b] > dist[x][y] + w )
                {
                    dist[a][b] = dist[x][y] + w;

                    if( w )
                        q.push_back( {a, b} );
                    else
                        q.push_front( {a, b} );
                }
            }
        }
    }
    if( dist[n][m] == 0x3f3f3f3f )
        return -1;
    else
        return dist[n][m];

}

int main()
{
    int T;
    cin >> T;
    while( T -- )
    {
        memset( st, 0, sizeof st );

        cin >> n >> m;

        for( int i = 0; i < n; i ++ )
            cin >> g[i];

        int t = bfs();

        if( t == -1 )
            cout << "NO SOLUTION" << endl;
        else
            cout << t << endl;
    }
}