/** @JUDGE_ID: GOKURI_SQUEEZE ??? C++ */ #include #include #include #include #include #include #include #include using namespace std; #define FNAME "erythea.txt" #define cin fin typedef vector< vector > vvint; typedef pair vert; typedef int len_t; typedef pair edge; typedef vector edges; typedef map graph; len_t dijkstra( graph& G, vert src, vert dst ) { set visited; priority_queue, greater > Q; Q.push( edge(0,src) ); while( !Q.empty() ) { edge c = Q.top(); Q.pop(); if( visited.count(c.second) ) continue; if( c.second == dst ) return c.first; visited.insert(c.second); edges& ne = G[c.second]; for(int i=0; i!=ne.size(); ++i) if( !visited.count(ne[i].second) ) Q.push( edge(c.first+ne[i].first, ne[i].second) ); } return -1; } int main() { ifstream fin(FNAME); if(!fin) return -1; int M; cin >> M; while(M--) { // read input int Y, X; cin >> Y >> X; int sy,sx,dy,dx; cin >> sy >> sx >> dy >> dx; vector< vector > flag( Y, vector(X) ); for(int y=0; y!=Y; ++y) for(int x=0; x!=X; ++x) { char c; cin >> c; flag[y][x] = c-'0'; } // TODO: calc risk levels vector< vector > risk( Y+1, vector(X+1,-1) ); for(int y=0; y<=Y; ++y) for(int x=0; x<=X; ++x) if( (y (y+1,x) if( y < Y ) { bool exist = x==0 || x==X || !(flag[y][x-1]&&flag[y][x]); if( exist ) G[vert(y,x)].push_back( edge(risk[y+1][x],vert(y+1,x)) ), G[vert(y+1,x)].push_back( edge(risk[y][x],vert(y,x)) ); } // (y,x) <==> (y,x+1) if( x < X ) { bool exist = y==0 || y==Y || !(flag[y-1][x]&&flag[y][x]); if( exist ) G[vert(y,x)].push_back( edge(risk[y][x+1],vert(y,x+1)) ), G[vert(y,x+1)].push_back( edge(risk[y][x],vert(y,x)) ); } } // shortest path is... len_t len = dijkstra( G, vert(sy,sx), vert(dy,dx) ); if( len >= 0 ) cout << len+risk[sy][sx] << endl; else cout << "no solution" << endl; } return 0; }