Blue Bridge Cup - Labyrinth (BFS)

  • Ideas
    The maze problem is essentially a shortest path problem. bfs+堆(先广搜索)It is generally used but not used for the shortest path problem dfs. Because dfs needs to backtrack repeatedly, the time complexity is very high, and bfseach node only needs to be traversed once, and the time complexity is O(n)(not counting heap sorting).
  • The principle of bfs to find the shortest
    path The idea of ​​bfs to find the shortest path is to find the shortest distance from the current node to the starting point in each round of traversal. If it is found that the shortest distance of the node has been found, then there is no need to traverse this node. Since bfs+堆the weight of each node is the shortest distance from the starting point to the node when it is traversed for the first time, in fact, each node only needs to be traversed once for a graph. bfs+堆The fact that the distance between each traversed node is guaranteed to be the smallest is based on the following fact: the
    shortest distance from the starting point to node i = min (the shortest distance from the starting point to the adjacent point of i) + 1 the shortest distance from the starting point to node i = min( The shortest distance from the starting point to the adjacent point of i)+1The shortest distance from the origin to node i=min ( the shortest distance from the starting point to the adjacent point of i )+1
  • Maze Question Template
  1. topic
  2. core code
//核心代码
void bfs(){
    
    
	//广度优先遍历
	priority_queue<Node,vector<Node>,Comp> minHeap;
	//放入第一个节点
	Node first=Node();
	first.path="";
	//表示当前点到起点的最短距离
	first.sum=0;
	first.x=first.y=1;
	minHeap.emplace(first);
	visited[1][1]=0;
	int x,y;
	int num=0;
	while(!minHeap.empty()){
    
    
		//非空不断的迭代
		Node head=minHeap.top();
		minHeap.pop();
		x=head.x;
		y=head.y;
		//先检查一下大小
		if(x==X&&y==Y){
    
    
			//到达出口 
			bestNum=head.sum;
			bestStr=head.path;
			num=1;
			return;
		} 
		if(head.sum>=bestNum)	break; 
		//上下左右
		for(int i=0;i<=3;i++){
    
    
			if(check(x+d[i][0],y+d[i][1])){
    
    
				
				//当前路径不是最短距离直接跳过 
				if((head.sum+1)>visited[x+d[i][0]][y+d[i][1]]) 	continue;
				//创建新节点
				Node newNode=Node();
				newNode.x=x+d[i][0];
				newNode.y=y+d[i][1];
				newNode.sum=head.sum+1;
				visited[newNode.x][newNode.y]=head.sum+1; 
				newNode.path=head.path+step[i];
				//插入堆中
				minHeap.emplace(newNode); 
			}
		}
	}
}
  1. template
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#include <bits/stdc++.h>
#include <fstream>
#include <vector>
#include <queue>
int X,Y;
using namespace std;
const int MAXNUM=2e9;
vector<vector<int>> m(31,vector<int>(51,0)); 
//表明一个点到起点的最短距离 
vector<vector<int>>	visited(31,vector<int>(51,MAXNUM));
int bestNum=MAXNUM;
string bestStr="";
int d[4][2]={
    
    {
    
    -1,0},{
    
    1,0},{
    
    0,-1},{
    
    0,1}};
string step[4]={
    
    "U","D","L","R"}; 
struct Node{
    
    
	int sum;
	string path;
	int x;
	int y; 
	vector<pair<int,int>>	nodeList;
	vector<vector<bool>> visited=vector<vector<bool>>(31,vector<bool>(51,false));
	Node(){
    
    
		
	}
};
class Comp{
    
    
	public:
		bool operator()(const Node &a,const Node &b){
    
    
			if(a.sum>b.sum){
    
    
				return true;
			}else if(a.sum==b.sum){
    
    
				
				return ((a.path.compare(b.path))>0);
			}else{
    
    
				return false;
			}
		}
}; 
bool check(int x,int y){
    
    
	return 1<=x&&x<=X&&1<=y&&y<=Y&&(m[x][y]==0);
}
//核心代码
void bfs(){
    
    
	//广度优先遍历
	priority_queue<Node,vector<Node>,Comp> minHeap;
	//放入第一个节点
	Node first=Node();
	first.path="";
	//表示当前点到起点的最短距离
	first.sum=0;
	first.x=first.y=1;
	minHeap.emplace(first);
	visited[1][1]=0;
	int x,y;
	int num=0;
	while(!minHeap.empty()){
    
    
		//非空不断的迭代
		Node head=minHeap.top();
		minHeap.pop();
		x=head.x;
		y=head.y;
		//先检查一下大小
		if(x==X&&y==Y){
    
    
			//到达出口 
			bestNum=head.sum;
			bestStr=head.path;
			num=1;
			return;
		} 
		if(head.sum>=bestNum)	break; 
		//上下左右
		for(int i=0;i<=3;i++){
    
    
			if(check(x+d[i][0],y+d[i][1])){
    
    
				
				//当前路径不是最短距离直接跳过 
				if((head.sum+1)>visited[x+d[i][0]][y+d[i][1]]) 	continue;
				//创建新节点
				Node newNode=Node();
				newNode.x=x+d[i][0];
				newNode.y=y+d[i][1];
				newNode.sum=head.sum+1;
				visited[newNode.x][newNode.y]=head.sum+1; 
				newNode.path=head.path+step[i];
				//插入堆中
				minHeap.emplace(newNode); 
			}
		}
	}
}
int main(int argc, char** argv) {
    
    
	fstream f;
	f.open("./test.txt",ios::in);
	string a;
	X=30;
	Y=50;
	for(int i=1;i<=X;i++){
    
    
		getline(f,a);
		for(int j=1;j<=Y;j++){
    
    
			if(a[j-1]=='0')	m[i][j]=0;
			else			m[i][j]=1;
		}
	}
	bfs();
	cout<<bestStr<<endl;
	return 0; 
}


Guess you like

Origin blog.csdn.net/qq_33880925/article/details/129583415