HDOJ 1728
http://acm.hdu.edu.cn/showproblem.php?pid=1728
BFS求最少转过的弯
#include <stdio.h> #include <string.h> #include <queue> using namespace std; int map[101][101]; int w[101][101]; //记录到当前点已经转过个弯,初始化为-1,检测该点是否已遍历 struct node { int x; int y; }now,temp; int dx[]={0,1,0,-1}; int dy[]={1,0,-1,0}; int m,n; bool BFS(int x1,int y1,int x2,int y2) { queue<node> q; int i; now.x=x1; now.y=y1; q.push(now); while(!q.empty()) { now=q.front(); for(i=0;i<4;i++) //向4个方向扩散搜索 { temp.x=now.x+dx[i]; temp.y=now.y+dy[i]; while(temp.x>=1&&temp.x<=n&&temp.y>=1&&temp.y<=m&&map[temp.y][temp.x]!='*') { if(w[temp.y][temp.x]==-1) { q.push(temp); w[temp.y][temp.x]=w[now.y][now.x]+1; if(temp.x==x2&&temp.y==y2) return true; } temp.x=temp.x+dx[i]; temp.y=temp.y+dy[i]; } //沿一个方向搜索 } q.pop(); } return false; } int main() { int t,i,j; int k,x1,y1,x2,y2; scanf("%d",&t); while(t--) { scanf("%d%d%*c",&m,&n); for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { scanf("%c",&map[i][j]); } getchar(); } scanf("%d%d%d%d%d",&k,&x1,&y1,&x2,&y2); memset(w,-1,sizeof(w)); if(x1==x2&&y1==y2) { printf("yes\n"); continue; } if(BFS(x1,y1,x2,y2)) { if(w[y2][x2]<=k) printf("yes\n"); else printf("no\n"); } else printf("no\n"); } return 0; }
广度优先搜索:
- 从初始点开始,根据规则展开第一层节点,并检查目标节点是否在这些节点上,若没有,再将所有的第一层的节点逐一展开,得到第二层节点,如没有,则扩展下去,直到发现目标节点为止。
- 比较适合求最少步骤或最短解序列的题目。
- 一般设置一个队列queue ,将起始节点放入队列中,然后从队列头取出一个节点,检查是否是目标节点,如不是则进行扩展,将扩展出的所有节点放到队尾,然后再从队列头取出一个节点,直至找到目标节点。