0
点赞
收藏
分享

微信扫一扫

算法笔记 8.2 BFS


1.BFS模板

//BFS模板
void BFS(int s){
    queue<int> q;//定义队列
    q.push(s);//起始结点入队
    while(!q.empty()){//非空循环
        取出队首元素top;
        访问队首元素top;
        队首元素出队;
        将top的下一层结点中未曾入队的结点全部入队,并设置为以入队;
    }
}

 

引例:求矩阵中相邻1块的个数(就是八连块个数 上下左右相邻才算一块)

例如下面第一1块的个数为4

先贴出测试数据

6 7 0 1 1 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 1 1 1 1 0 0 0 6 7 0 1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 0 0 0 6 7 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 2 1 0 0 1 1 0 5 6 1 1 0 1 1 1 1 0 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 1 25 25 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1

 

上节的DFS实现,(简单一点)

#include<iostream> using namespace std; const int N=30; int n,m; int a[N][N]; // bool visited[N][N]={0};//开始都为false 没用到 直接赋值为2即可 省略可这一步 否则每次都要初始化 int num; void dfs(int i,int j){ if(i<0||j<0||i>=n||j>=m) return; if(a[i][j]!=1) return;//1行不等于即可 都是后置判断 不会忽略第一个什么的 a[i][j]=2; dfs(i,j+1); dfs(i,j-1); dfs(i+1,j); dfs(i-1,j); } void print(int a[N][N]){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<a[i][j]<<" "; } cout<<endl; } cout<<endl; } int main(){ freopen("lx1dfs.txt","r",stdin); while(cin>>n>>m){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>a[i][j]; } } num=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(a[i][j]==1){ num++; dfs(i,j); } } } cout<<num<<endl; //输出处理后的数组 // print(a); } return 0; }

算法笔记 8.2 BFS_#include

 

bfs实现:(自己实现,改了个大bug,关于inqueue的含义)

原始代码:

#include<iostream> #include <algorithm> #include <cstring> #include <queue> #include<ctime> using namespace std; const int N=100; int n,m,matrix[N][N],num; // bool inque[N][N]={false}; //还是不要 直接将值置为2 int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; struct Node{ int x,y; Node(){} Node(int x,int y){ this->x=x; this->y=y; } }; void print(int a[N][N]){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<a[i][j]<<" "; } cout<<endl; } cout<<endl; } bool judge(Node node){ if(node.x<0||node.x>=n||node.y<0||node.y>=m) return false; if(matrix[node.x][node.y]!=1) return false; return true; } //没有递归 只有循环 void bfs(Node node){ queue<Node> q; q.push(node); matrix[node.x][node.y]=2;//入队了 time_t start ,end; double cost; time(&start); while(!q.empty()){ Node top=q.front(); q.pop(); //严重错误 改正后加了两行43 56 //正确做法 每次入队一个置一个2 或者bool数组置为true //不可以在此处写matrix[top.x][top.y]=2; 然后其他地方不写 //因为入队元素太多,有些尚未来得及pop(),又没有做标记,可能导致循环push //也即是push后没有立马置为2 可能导致多次push 最终可能陷入死循环 //正确操作,每push一次 置一次2 for(int i=0;i<4;i++){ Node nextno=Node(top.x+dx[i],top.y+dy[i]); if(judge(nextno)){ q.push(nextno); matrix[nextno.x][nextno.y]=2;//入队了 } } time(&end); cost=difftime(end,start); if(cost>=2){ print(matrix); time(&start); } } } int main(){ freopen("input1.txt","r",stdin); while(cin>>n>>m){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>matrix[i][j]; } } num=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(matrix[i][j]==1){ num++; Node node=Node(i,j); bfs(node); } } } cout<<num<<endl; print(matrix); } return 0; }

原始代码运行结果:

4 0 2 2 2 0 0 2 0 0 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 2 2 0 2 2 2 0 2 0 0 2 2 2 2 0 0 0 5 0 2 2 2 0 0 2 0 0 2 0 0 0 0 2 2 0 0 2 0 0 0 0 0 2 2 2 2 2 2 2 0 2 0 0 2 2 2 2 0 0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 2 0 0 2 2 0 7 2 2 0 2 2 2 2 0 2 0 2 0 2 0 0 2 0 2 0 2 2 0 2 0 2 0 2 2 2 2 15 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 0 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 0 2 2 2 2 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 0 2 2 2 2 0 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 0 2 2 2 2 0 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 0 2 0 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 0 0 0 0 0 2 2 2 2 2 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 0 2 2 2 2 2 0 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 0 2 0 2 2 2 2 2 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 0 0 2 0 0 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 2 2 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 请按任意键继续. . .

 

化简后的代码:

#include<iostream> #include <cstring> #include <queue> using namespace std; const int N=100; int n,m,matrix[N][N],num; // bool inque[N][N]={false}; //还是不要 直接将值置为2 int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; struct Node{ int x,y; Node(){} Node(int x,int y){ this->x=x; this->y=y; } }; bool judge(Node node){ if(node.x<0||node.x>=n||node.y<0||node.y>=m) return false; if(matrix[node.x][node.y]!=1) return false; return true; } //没有递归 只有循环 void bfs(Node node){ queue<Node> q; q.push(node); matrix[node.x][node.y]=2;//入队了 while(!q.empty()){ Node top=q.front(); q.pop(); //严重错误 改正后加了两行43 56 //正确做法 每次入队一个置一个2 或者bool数组置为true //不可以在此处写matrix[top.x][top.y]=2; 然后其他地方不写 //因为入队元素太多,有些尚未来得及pop(),又没有做标记,可能导致循环push //也即是push后没有立马置为2 可能导致多次push 最终可能陷入死循环 //正确操作,每push一次 置一次2 for(int i=0;i<4;i++){ Node nextno=Node(top.x+dx[i],top.y+dy[i]); if(judge(nextno)){ q.push(nextno); matrix[nextno.x][nextno.y]=2;//入队了 } } } } int main(){ freopen("input1.txt","r",stdin); while(cin>>n>>m){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>matrix[i][j]; } } num=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(matrix[i][j]==1){ num++; Node node=Node(i,j); bfs(node); } } } cout<<num<<endl; // print(matrix); } return 0; }

化简后代码运行结果:

算法笔记 8.2 BFS_#include_02

 

书上的代码:

#include <cstdio> #include <queue> #include <algorithm> using namespace std; const int maxn=100; struct node { int x,y; }Node; int n,m; int matrix[maxn][maxn]; bool inq[maxn][maxn]={false}; int X[4]={0,0,1,-1}; int Y[4]={1,-1,0,0}; bool judge(int x,int y){ if(x>=n||x<0||y>=m||y<0) return false; if(matrix[x][y]==0||inq[x][y]==true) return false; return true; } void BFS(int x,int y){ queue<node> Q; Node.x=x,Node.y=y; Q.push(Node); inq[x][y]=true; while(!Q.empty()){ node top=Q.front(); Q.pop(); for(int i=0;i<4;i++){ int newX=top.x+X[i]; int newY=top.y+Y[i]; if(judge(newX,newY)){ Node.x=newX,Node.y=newY; Q.push(Node); inq[newX][newY]=true; } } } } int main(){ freopen("input1.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF){ for(int x=0;x<n;x++){ for(int y=0;y<m;y++){ scanf("%d",&matrix[x][y]); } } int ans=0; fill(inq[0],inq[0]+maxn*maxn,false); for(int x=0;x<n;x++){ for(int y=0;y<m;y++){ if(matrix[x][y]==1&&inq[x][y]==false){ ans++; BFS(x,y); } } } printf("%d\n", ans); } return 0; }

算法笔记 8.2 BFS_i++_03

 

特别强调:在BFS中设置的inque数组的含义是判断结点是否已入过队,而不是结点是否已被访问。区别在于:如果设置成是否已被访问,有可能在某个结点正在队列中(但还未访问)时由于其他结点可以到达它而将这个结点再次入队,导致很多结点反复入队,计算量大大增加。甚至可能发生死循环。因此BFS中让每个结点只入队一次,故需要设置inque数组的含义为结点是否已入队而非结点是否被访问过。

 

bug版本如下: 最后一组测试数据有bug

#include<iostream> #include <algorithm> #include <cstring> #include <queue> #include<ctime> using namespace std; const int N=100; int n,m,matrix[N][N],num; // bool inque[N][N]={false}; //还是不要 直接将值置为2 int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; struct Node{ int x,y; Node(){} Node(int x,int y){ this->x=x; this->y=y; } }; void print(int a[N][N]){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<a[i][j]<<" "; } cout<<endl; } cout<<endl; } bool judge(Node node){ if(node.x<0||node.x>=n||node.y<0||node.y>=m) return false; if(matrix[node.x][node.y]!=1) return false; return true; } //没有递归 只有循环 void bfs(Node node){ queue<Node> q; q.push(node); //入队不设置标记 time_t start ,end; double cost; time(&start); while(!q.empty()){ Node top=q.front(); q.pop(); matrix[top.x][top.y]=2;//访问了 for(int i=0;i<4;i++){ Node nextno=Node(top.x+dx[i],top.y+dy[i]); if(judge(nextno)){ q.push(nextno); //入队不设置标记 } } time(&end); cost=difftime(end,start); if(cost>=2){ print(matrix); time(&start); } } } int main(){ freopen("input1.txt","r",stdin); while(cin>>n>>m){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>matrix[i][j]; } } num=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(matrix[i][j]==1){ num++; Node node=Node(i,j); bfs(node); } } } cout<<num<<endl; print(matrix); } return 0; }

运行结果:死循环

4 0 2 2 2 0 0 2 0 0 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 2 2 0 2 2 2 0 2 0 0 2 2 2 2 0 0 0 5 0 2 2 2 0 0 2 0 0 2 0 0 0 0 2 2 0 0 2 0 0 0 0 0 2 2 2 2 2 2 2 0 2 0 0 2 2 2 2 0 0 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 2 0 0 2 2 0 7 2 2 0 2 2 2 2 0 2 0 2 0 2 0 0 2 0 2 0 2 2 0 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 0 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 0 2 2 2 2 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 0 2 2 2 1 1 1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 1 0 2 2 1 1 1 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 1 0 2 1 1 1 0 1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 0 1 0 1 1 1 1 0 1 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 1 1 1 1 0 1 0 1 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 0 1 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 0 1 0 1 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 0 1 1 1 2 2 2 2 0 0 0 0 0 2 2 2 2 1 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 0 1 1 0 2 2 2 2 1 0 1 1 1 0 1 1 1 1 1 1 1 2 2 2 2 0 1 0 1 2 2 2 1 0 0 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 0 0 1 1 1 2 1 1 1 0 0 1 0 0 1 1 1 1 1 1 1 2 2 2 2 0 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 0 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 2 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 0 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 0 2 2 2 2 2 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 0 2 2 2 2 1 1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 1 0 2 2 2 1 1 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 0 1 1 1 0 2 2 1 1 0 1 0 0 2 2 2 2 2 2 2 2 2 2 2 2 0 0 1 0 1 2 1 1 0 1 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 1 1 1 1 0 1 0 1 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 0 1 0 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 0 1 0 1 1 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 0 1 1 1 2 2 2 2 0 0 0 0 0 2 2 2 2 2 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 0 1 1 0 2 2 2 2 2 0 1 1 1 0 1 1 1 1 1 1 1 2 2 2 2 0 1 0 2 2 2 2 2 0 0 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 0 0 2 1 2 2 2 1 1 0 0 1 0 0 1 1 1 1 1 1 1 2 2 2 2 0 2 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 0 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 2 2 2 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 2 2 2 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1

 

 

 

2.起点到终点最短距离

给定一个n*m大小的迷宫,其中*代表不可通过的墙壁,而“.”代表平地,S代表起点,T代表终点。移动过程中,如果当前位置是(x,y)(下标从0开始)且每次只能前往上下左右(x,y+1),(x,y-1),(x-1,y),(x+1,y)四个位置的平地,求从起点S到达终点T的最少步数

. . . . .
. * . * .
. * S * .
. * * * .
. . . T *
S(2,2)  T(4,3)

 

解析:最短步数就是BFS访问到改结点的层数

#include<iostream>
#include <queue>
#include <algorithm>
using namespace std;

const int N=30;
int n,m;
char a[N][N];
bool inque[N][N]={false};
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct Node
{
int x,y;
int step;
Node(){step=0;}
Node(int x,int y){this->x=x;this->y=y;step=0;}
}start,end;

bool judge(Node node){
if(node.x<0||node.x>=n||node.y<0||node.y>=m) return false;
//不能写!='.' 因为S T也可以通过
if(a[node.x][node.y]=='*'||inque[node.x][node.y]==true) return false;
return true;
}

void bfs(Node start){
queue<Node> q;
q.push(start);
start.step=0;
inque[start.x][start.y]=true;
while(!q.empty()){
Node top=q.front();
q.pop();
if(a[top.x][top.y]=='T'){
//找到了 输出层数(最短步数) 直接return
cout<<top.step<<endl;
return;
}

for(int i=0;i<4;i++){
Node next=Node(top.x+dx[i],top.y+dy[i]);
if(judge(next)){
next.step=top.step+1;//放到push后面赋值还不行 注意c/c++结构体名做参数入栈传递的是副本 不是地址
q.push(next);
inque[next.x][next.y]=true;
}
}
}

cout<<"无可达路径\n";
}


int main(){
freopen("input2.txt","r",stdin);
while(cin>>n>>m){
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
if(a[i][j]=='S'||a[i][j]=='s'){
start.x=i;start.y=j;
}else if(a[i][j]=='T'||a[i][j]=='t'){
end.x=i;end.y=j;
}
}
}
fill(inque[0],inque[0]+N*N,false);
// cout<<"start:"<<start.x<<" "<<start.y<<endl;
// cout<<"end:"<<end.x<<" "<<end.y<<endl;
bfs(start);
}

return 0;
}

测试数据与运行结果:

测试数据:
5 5
. . . . .
. * . * .
. * S * .
. * * * .
. . . T *



5 6
. . . . . .
. * . * . .
. * S * . *
. * * * . *
. . . T . .


25 25
. . . . * . . . . . . . . . . . . . . . . . . . .
. * * . . * . . . . . . . . . . . . . . . . . . .
. . . * . * . . . . . . . . . . . . . . . . . . .
. . . * . * * * * * * * * * * . . . . . . . . . .
. . . * . . . . . . . . . . * . . . . . . . . . .
. . . . * * * * * * . . . . * . . . . . . . . . .
. . . . . . . . . S * * * . . * . . . . . . . . .
. . . . . . . . . . * T * . . * . . . . . . . . .
. . . . . . . . . . * . . * . * . . . . . . . . .
. . . . . . . . . . * . . * . * . . . . . . . . .
. . . . . . . . . . * . . * . * . . . . . . . . .
. . . . . . . . . . * . . * . * . . . . . . . . .
. . . . . . . . . . * . . * . * . . . . . . . . .
. . . . . . . . . . * . * . . * . . . . . . . . .
. . . . . . . . . . * . * . * * . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . * . * . . . . . . . . . .
. . . . . . . . . . * . . . . . . . . . . . . . .


运行结果:
11
9
73

注意点2:当使用STL的queue时,元素入队的push操作只是制造了该元素的一个副本入队,因此在入队后对原元素的修改不会影响队列中的副本,而对队列中的副本的修改也不会改变原元素,需要注意由此可能引入的bug(一般由结构体产生)

例如上面例子44行若写在45行之后则会导致出错!

​​相关链接​​

 

举报

相关推荐

0 条评论