BFS的记录

对于BFS的一些疑惑
首先,BFS是从中心向四个方向蔓延过去,之前首先看到的是leetcode推箱子力扣推箱子的这段定义结构体的最优队列的BFS

class Solution {
public:
struct Node{
    Node(int x0,int y0,int bx0,int by0){
        x=x0;y=y0;
        bx=bx0;by=by0;
    }
    int x,y;
    int bx,by;
    friend bool operator < (const Node a,const Node b){
        if(a.x!=b.x) return a.x<b.x;
        if(a.y!=b.y) return a.y<b.y;
        if(a.bx!=b.bx) return a.bx<b.bx;
        return a.by<b.by;
    }
};
int cx[4]={0,1,0,-1};
int cy[4]={1,0,-1,0};
map<Node,int>dis;
map<Node,bool>inQue;
    int minPushBox(vector<vector<char>>& grid) {
        int n=grid.size(),m=grid[0].size();
        int sx,sy,ex,ey,bx,by;

        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
        if(grid[i][j]=='T') ex=i,ey=j,grid[i][j]='.';
        if(grid[i][j]=='S') sx=i,sy=j,grid[i][j]='.';
        if(grid[i][j]=='B') bx=i,by=j,grid[i][j]='.';
        }

        dis.clear();inQue.clear();
        queue<Node>Q;
        while(!Q.empty()) Q.pop();
        Node p(sx,sy,bx,by);
        Q.push(p);
        inQue[p]=true;
        dis[p]=0;
        int ans=-1;

        while(!Q.empty()){
            int x=Q.front().x,y=Q.front().y,bx=Q.front().bx,by=Q.front().by,count=dis[Q.front()];
            inQue[Q.front()]=false;
            Q.pop();

            if(bx==ex&&by==ey){
            if(ans>count||ans==-1) ans=count;
            continue;
            }
            for(int i=0;i<4;i++)
            {
                int flag=0;
                int nx=x+cx[i],ny=y+cy[i];
                int nbx=bx,nby=by;
                if(nx<0||nx>=n||ny<0||ny>=m) continue;
                if(grid[nx][ny]=='#') continue;

                if(nx==bx&&ny==by){
                if(bx+cx[i]<0||bx+cx[i]>=n||by+cy[i]<0||by+cy[i]>=m) continue;
                if(grid[bx+cx[i]][by+cy[i]]=='.') nbx+=cx[i],nby+=cy[i],flag=1;
                }

                Node temp(x+cx[i],y+cy[i],nbx,nby);
                if(dis.count(temp)==0||dis[temp]>count+flag){
                dis[temp]=count+flag;
                if(!inQue[temp])
                {
                    inQue[temp]=true;
                    Q.push(temp);
                }
            }
            }
        }
        return ans;
    }
};

这个是用map来存某个状态的最短次数,还有一个inQue来判断某个状态是否入队,因为已经入队的话就没必要再次入队了。因为这个的最短次数是不均匀的即不是从小到大排列的,所以需要对比所有到终点的路径然后选择最小次数的那个。而后来我在2015蓝桥杯有一题叫穿越雷区
这个的话其实是DFS和BFS都能用,然后在我用BFS的时候我发现因为这种距离是均匀的,先是把距离为1的全遍历完,接下来是把距离为2的全遍历完,所以只要能走到终点,第一条路一定是路径最短的了,而且在进行队列优化的时候,只要注意走过的路不要再走就行了,这样想变得简单很多。附上优化的代码

#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
struct Node{
	Node(int x0,int y0){
		x=x0;y=y0;
	}
	int x,y;
};
int sx,sy,ex,ey;
bool vis[105][105];
int dist[105][105];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int Solve(vector<string>grid){
	int n=grid.size();
	memset(vis,false,sizeof(vis));
	dist[sx][sy]=0;
	vis[sx][sy]=true;
	
	queue<Node>que;
	while(!que.empty()) que.pop();
	
	que.push(Node(sx,sy));
	while(!que.empty()){
		Node v=que.front();que.pop();
		int cx=v.x,cy=v.y,step=dist[cx][cy];
		
		if(cx==ex&&cy==ey) return step; 
		
		for(int k=0;k<4;k++){
			int vx=cx+dx[k];
			int vy=cy+dy[k];
			if(vx<0||vy<0||vx>=n||vy>=n||vis[vx][vy]||grid[cx][cy]==grid[vx][vy]) continue;
			dist[vx][vy]=step+1;
			vis[vx][vy]=true;
			que.push(Node(vx,vy));
	}
	}
	return -1;
}
int main(){
	int num; cin>>num;
	vector<string>grid(num,"");
	for(int i=0;i<num;i++)
		for(int j=0;j<num;j++){
			char c;cin>>c;
			if(c=='A') sx=i,sy=j;
			else if(c=='B') ex=i,ey=j;
			grid[i]+=c;
		}
		
		int ans=Solve(grid);
		cout<<ans;
		return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值