/* GNC type3 ikaryaku */ #include #include #include #include #include #include #include using namespace std; typedef pair point; struct edge{ point dest; int w; edge(){} edge(const point & dest,int w) : dest(dest) , w(w) {} }; typedef vector edges; typedef map graph; typedef map potential; potential dijkstra(graph g,const point &st) { potential pot; deque toBeProcessed; toBeProcessed.push_back(st); pot[st] = 0; while(!toBeProcessed.empty()){ point p = toBeProcessed.front() ; toBeProcessed.pop_front(); edges& es = g[p]; for(edges::iterator it = es.begin() ; it != es.end() ; ++it){ int newdist = pot[p] + it->w; if(pot.count(it->dest) == 0 || pot[it->dest] > newdist){ pot[it->dest] = newdist; toBeProcessed.push_back(it->dest); } } } return pot; } /* void makeedge(graph& g, point src,string dist,int w) { g[src].push_back(edge(dist,w)); g[dist].push_back(edge(src,w)); } */ int x, y; int srcx, srcy; int destx, desty; vector > risk_m; vector > m; graph thegraph; void calc_risk() { risk_m = vector > (x+3, vector(y+3, -1)); bool rest; while(1){ rest = false; vector > risk_next(risk_m); for(int q = 1; q < y + 2; q++){ for(int p = 1; p < x + 2; p++){ if(risk_m[p][q] != -1) continue; if(m[p-1][q-1] || m[p-1][q] || m[p][q-1] || m[p][q]){ risk_next[p][q] = x + y; rest = true; continue; } int m; m = max(risk_m[p-1][q], risk_m[p+1][q]); m = max(m, risk_m[p][q-1]); m = max(m, risk_m[p][q+1]); if(m == -1) continue; risk_next[p][q] = m - 1; rest = true; continue; } } risk_m = risk_next; if(!rest) break; } } void add_edge_if(int x1, int y1, int x2, int y2, int dir) { point src = make_pair(x1, y1); point dest = make_pair(x2, y2); switch(dir) { case 0: // up if(y1 <= 1) return; if(m[x1-1][y1-1] && m[x1][y1-1]) return; thegraph[src].push_back(edge(dest,risk_m[x2][y2])); break; case 1: // down if(y1 >= y+1) return; if(m[x1-1][y1] && m[x1][y1]) return; thegraph[src].push_back(edge(dest,risk_m[x2][y2])); break; case 2: if(x1 <= 1) return; if(m[x1-1][y1-1] && m[x1-1][y1]) return; thegraph[src].push_back(edge(dest,risk_m[x2][y2])); break; case 3: if(x1 >= x +1) return; if(m[x1][y1-1] && m[x1][y1]) return; thegraph[src].push_back(edge(dest,risk_m[x2][y2])); break; } } void create_graph() { thegraph = graph(); for(int p = 1; p < x + 2; p++){ for(int q = 1; q < y + 2; q++){ add_edge_if(p, q, p, q-1, 0); add_edge_if(p, q, p, q+1, 1); add_edge_if(p, q, p-1, q, 2); add_edge_if(p, q, p+1, q, 3); } } } int main(void) { int n; ifstream ifs("erythea.txt"); ifs >> n; for( int nc = 0; nc < n; nc++){ ifs >> y >> x; ifs >> srcy >> srcx; ifs >> desty >> destx; char c; m = vector > (x + 2, vector ( y + 2, 0)); for( int q = 0; q < y; q ++){ for( int p = 0; p < x; p++){ ifs >> c; m[p + 1][q + 1] = (c == '1' ? 1 : 0); } } calc_risk(); create_graph(); potential pot = dijkstra(thegraph, make_pair(srcx +1, srcy + 1)); /* cout << "GNC" << endl; for(int q = 0; q < y + 3; q++){ for(int p = 0; p < x + 3; p++){ printf("% 4d", (int)pot[make_pair(p,q)]); } printf("\n"); }*/ if( pot[make_pair(destx + 1, desty + 1)] == 0 && (srcx != destx || srcy != desty) ) cout << "no solution" <