http://acm.hdu.edu.cn/showproblem.php?pid=1175
与普通的BFS不同的是这里的vis数组不是标记是否被访问过,而是记录到这个点的最小转弯次数。
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; int grid[1100][1100]; int vis[1100][1100]; int dire[5][2] = {{0,0},{1,0},{0,-1},{-1,0},{0,1}}; struct node { int x,y; int dir;//到达这点的方向,规定向下为1,向左为2,向上为3,向右为4. int turn;//转弯次数 }; int n,m; int BFS(int x1, int y1, int x2, int y2) { if(grid[x1][y1] == 0 || grid[x2][y2] == 0) return 0; if(grid[x1][y1] != grid[x2][y2]) return 0; queue<struct node> que; while(!que.empty()) que.pop(); que.push((struct node){x1,y1,-1,0});//起点进队列,方向为-1,转弯次数为0. while(!que.empty()) { struct node u = que.front(); que.pop(); if(u.x == x2 && u.y == y2) return 1; for(int i = 1; i <= 4; i++) { int xx = u.x+dire[i][0]; int yy = u.y+dire[i][1]; if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && (grid[xx][yy] == 0 ||(xx == x2 && yy == y2))) { if(u.dir == -1) { que.push((struct node){xx,yy,i,0}); vis[xx][yy] = 0; } else if(u.dir == i && vis[xx][yy] >= u.turn) { que.push((struct node){xx,yy,i,u.turn}); vis[xx][yy] = u.turn; } else { if(u.turn < 2 && vis[xx][yy] >= u.turn+1) { que.push((struct node){xx,yy,i,u.turn+1}); vis[xx][yy] = u.turn+1; } } } } } return 0; } int main() { while(~scanf("%d %d",&n,&m) && (n || m)) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) scanf("%d",&grid[i][j]); } int q,x1,y1,x2,y2; scanf("%d",&q); while(q--) { memset(vis,INF,sizeof(vis)); scanf("%d %d %d %d",&x1,&y1,&x2,&y2); if(x1 < 1 || x2 < 1 || x1 > n || x2 > n || y1 < 1 || y2 < 1 || y2 > m || y1 > m) { printf("NO\n"); continue; } if(BFS(x1,y1,x2,y2)) printf("YES\n"); else printf("NO\n"); } } return 0; }