bfs 학습 기록 : 템플릿 / 아이디어 요약

HB 소금에 절인 생선 학습 기록 *

약간의 의견

Lanqiao Cup에는 많은 검색 질문이 있지만 bfs 질문은 거의 없으며 대부분 dfs 질문입니다.
그런데 작년에 블루 브릿지 컵이 BFS 시험을 봤기 때문에 문제를 잘 공부해야 해요.
bfs는 루프에서 검색하므로 역 추적 할 수 없으므로 각 지점은 한 번만 걸을 수 있습니다. 이렇게하면 검색 속도가 빨라지지만 각 지점은 한 번만 걸을 수 있으므로 가능한 모든 경로를 나열 할 수 없습니다. 그리고 이것의 장점은 우회를 피하는 것이며 검색 결과를 찾을 때 가장 짧은 경로 여야합니다. 따라서 대부분의 최단 경로 질문은 bfs를 사용합니다.

"폭 우선 검색"에 대한 나의 이해

bfs는 말 그대로 폭을 먼저 차지하는 검색 방법입니다. 검색 할 때 원점에서 퍼집니다. dfs가 "한 방을 검색 한 다음 다른 방을 검색"하는 경우 bfs는 "각 방의 캐비닛을 검색 한 다음 각 방의 테이블을 검색합니다 ..."이러한 종류의 심층 검색입니다. 이렇게하면 항목이있을 수있는 위치를 검색하는 데 우선 순위를 부여하여 검색 시간을 줄일 수 있습니다.
미로를 앞, 좌, 우 순으로 걷도록 규정 한 것처럼 미로의 출구를 찾을 때는 수색이라고 할 수있다. 먼저 첫 번째 교차로에서 갈 수있는 교차로를 기록한 다음이 교차로에서 지정된 순서 (앞 왼쪽 및 오른쪽)로 갈 수있는 교차로를 확인합니다. 도중에 방문한 교차로는 반복 점검을 방지하기 위해 표시해야합니다. 교차로가 보일 때까지 끝 또는 끝으로 갈 수 있으며 검색이 종료됩니다. 우리가 보는 라운드 수는 끝까지의 최소 단계 수입니다. 검색 프로세스에서 적절한 데이터 구조를 사용하여 가장 짧은 경로 인 대상에 전달한 교차점을 저장할 수 있습니다.
이러한 방식으로 검색 범위가 넓고 목적지까지의 경로가 항상 최단 경로입니다. 그러나 단점은 목적지까지의 모든 경로를 반복 할 수 없다는 것입니다.

bfs의 일반적인 아이디어

우선 , 이전 단편에서 언급했듯이 먼저 미로를 표시하고 걸을 수있는 지점과 장애물 (걸을 수없는 지점)을 표시하는 2 차원 배열이 필요합니다.
둘째 , 대기열을 만들고 대기열에 시작점을 추가합니다.
다음으로 큐가 비어 있지 않을 때 루프를 실행하도록 설정하는 while 루프를 만듭니다.
루프에서 먼저 큐의 헤드 노드 좌표를 얻은 다음 이동 규칙을 지정해야합니다. 예를 들어, 위의 예에서 지정한 "위, 왼쪽, 오른쪽"은 2 차원 배열을 사용하여 이동 후 좌표 변경 사항을 저장할 수 있습니다.

int direction[4][2] = {
    
    {
    
    0,-1},{
    
    -1,0},{
    
    1,0},{
    
    0,1}}; 

이 배열의 네 가지 데이터 세트는 각각 "위, 왼쪽, 오른쪽 및 아래"를 나타내며 좌표 변환 중에 수행됩니다.

	int x1=x+direction[a][0];
	int y1=y+direction[a][1]; 

그러면 좌표 변경이 실현 될 수 있습니다. 이 순서로 헤드 노드의 주변을 판단하고, 갈 수 있으면 변환 된 데이터 포인트를 큐에 추가합니다. 그런 다음 새 점 (x1, y1)의 상태를 변경하여 여기에 있음을 나타냅니다. 반복 검색을 방지합니다.
마지막으로 이전 단계의 종료 조건을 설정하여 종료가 발견되면 일부 정보를 중지하거나 반환해야합니다. 루프에서 헤드 노드를 가져온 후 판단을 내리는 경우가 많으며, 검색하고자하는 정보가 헤드 노드 데이터라면 루프를 멈 춥니 다.

BFS의 대략적인 템플릿

void BFS(传入的数据)
{
    
    
	queue<int>q; //建立一个队列
	q.push(初始坐标); //把头结点(初始点)加入队列
	while(队列不为空) 
	{
    
    
		top = q.front(); //取出队首元素top
		if(队首元素top就是你要搜索的目标) 
		{
    
    
			执行一些操作
			return;
		}
		top.pop(); //将队首元素出队;
		for(按顺序寻找top的所有子节点)
		{
    
    
			把可以前往的子节点入队
			标记入队的子节点,防止下次重复入队
		}
	}
} 

bfs 예

블루 브리지 컵 Xueba의 미로

질문 스템
입력 샘플
입력 샘플 1 :
3 (3)
001
100
110
샘플 출력의
출력 샘플 1 :
4
RDRD

주제 링크

이 질문은 bfs의 전형적인 예라고 할 수 있는데,이 질문은 가장 짧은 단계 수를 요구할뿐만 아니라 최단 경로를 출력하기도합니다.
그래서 특정 지점까지의 최단 경로를 저장하기 위해 큐 노드의 데이터 구조에 문자열을 추가했습니다.
끝점을 찾을 때 가장 짧은 단계 수와 가장 짧은 경로를 출력합니다.
ac 코드 :

#include<bits/stdc++.h> 
using namespace std;

struct data	//队列里的数据结构 
{
    
    
	int x;	//坐标x 
	int y;	//坐标y 
	int times;	//步数 
	string road;	//走过的路径
	data(int a,int b,int d,string c)	//构造函数 
	{
    
    
		x=a;
		y=b;
		times=d;
		road = c;	
	}	
};
queue<data>datas;	//队列用来存放点位数据 
bool maps[501][501];	//存放迷宫地图的点位 false代表可前往 true代表不可前往 
char fx[] = {
    
    'D','L','R','U'};	//方向ascii码从小到大排列 
int site[4][2] = {
    
    {
    
    0,1},{
    
    -1,0},{
    
    1,0},{
    
    0,-1}};	//下 左 右 上的坐标变化 

void bfs(int n,int m)	//传参为迷宫的大小 n为宽 m为长 
{
    
    
	datas.push(data(1,1,0,""));	//把起始点压入队列 
	maps[1][1]=true;	//标记初始点已走过 
	while(!datas.empty())	//如果队列不为空 
	{
    
    
		data now = datas.front();	//声明一个结构体变量 让now变量指向队列的头结点
		datas.pop();	//弹出头结点 
		//cout<<now.x<<" "<<now.y<<endl; 
		if(now.x==n&&now.y==m)	//如果头结点就是要找的点 就搜索结束 
		{
    
    
			cout<<now.times<<endl<<now.road<<endl;	//输出走过的路径 和步数 
			return; 
		} 
		for(int temp=0;temp<4;temp++)	//开始查找该点的四周点位 (因为只有上下左右4个走法 所以循4次 
		{
    
    
			int x1=now.x+site[temp][0];	//变换过的x坐标 
			int y1=now.y+site[temp][1]; //变换过的y坐标 
			if(maps[y1][x1])	//如果该点已经走过或者有障碍 跳过 
				continue;
			if(x1<1||y1<1||x1>n||y1>m) 	//如果坐标超出范围 就跳过此循环
				continue;
			datas.push(data(x1,y1,now.times+1,now.road+fx[temp]));	//把新点位压入队列 路径加上新选择的fx[temp] 
			maps[y1][x1] = true;	//标记已走过 
		}
	} 
}

int main()
{
    
    
	memset(maps,false,sizeof(maps));		//初始化 
	int x,y;	//接收迷宫大小
	char input;	
	cin>>y>>x;
	getchar();
	for(int y1=1;y1<=y;y1++) 	//迷宫长 
	{
    
    
		for(int x1=1;x1<=x;x1++)	//迷宫宽 
		{
    
    
			cin>>input;
			if(input=='1')
				maps[y1][x1]=true;	//如果输入是1就标记不可走
		}
		getchar();
	}
 	
 	bfs(x,y);	//bfs 迷宫长宽 与 xy坐标是相反的 所以传反着的坐标 
	
	return 0;
}

요약

bfs 사용시 토픽 데이터에 따라 적절한 데이터 유형을 선택해야합니다.
BFS 질문은 종종 최단 경로의 길이를 출력 할 수있을뿐만 아니라 일반적으로 다른 것을 가져 오므로 데이터를 저장할 적절한 구조를 설정해야합니다.
bfs의 공통 환경은
일반적으로 가중치가없는 그래프의 최단 경로를 찾는 데 사용됩니다. 질문의 핵심 단어는 종종 "도달 할 수 있습니까"와 "최단 경로"입니다.
현재 블루 브릿지 컵에서 bfs에 대한 조사 정도는 dfs보다 낮은 경우가 많지만 최근에는 블루 브릿지 컵에서 bfs에 대한 조사도 증가하고있어 잘 연습 할 필요가있다.
요컨대, 더 많은 질문을 풀고 더 많은 경험을 축적하는 것이 좋습니다.

추천

출처blog.csdn.net/qq_45698148/article/details/108013725