小結一下BFS模板
(後面有單獨的bfs小結)
寫 一下做BFS 的思路。因爲這題比較簡單,代碼量相對較少,也容易理解一些 更容易總結出模板
1、
先定義有關變量,一般是一個邊界值、一個初始值、一個標記數組、加上一個 數組(一個變量) pair<>類型 (兩個變量,如 x,y 座標類型) 或 struct 定義一個新的類(三個以上變量)
2.
按照題意先建立主函數,如果是迷宮類問題,讀入的可以直接用一層for循環加 %s 字符串,如果用兩層for循環加 %c 字符的話要記得加getchar()
3.
最好bfs不要定義成int型,容易出現BUG(都是淚)。結果傳遞的時候注意 邊界判斷的 if 的位置,一般在while( q.size() )循環裏 for()循環外。也不排除在for裏面。
4.
到了最關鍵的bfs函數部分(……),bfs是寬度/廣度搜索的簡稱,所以和dfs比起來,它有限搜索所有子節點,再搜索孫節點,以此類推。
在運用的時候一般是 隊列/優先隊列 + 一個模擬用的for + 一個判斷用的judge(可以寫在裏面)來構成(如果用優先隊列的話要記得重構)。
5.
運用時:先用for模擬所有的可能,然後判斷是否加入隊列,如果不符合,就自動進入下一個隊列元素的循環(循環開始時該元素在隊列中已經刪除)。
否則的話就把該元素加入隊列,並把計數數組vis加一。
6.
直到找到了ed(結束值)或者隊列爲空,循環結束。
——————————————————————————————————————————————-——
Catch That Cow
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12305 Accepted Submission(s): 3823
Problem Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
- Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
- Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
Input
Line 1: Two space-separated integers: N and K
Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input
5 17
Sample Output
4
HintThe fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.
Source
USACO 2007 Open Silver
Recommend
teddy | We have carefully selected several similar problems for you: 2102 1372 1240 1072 1180
————————————————————————————————————————————————
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int MAX_N = 1e5+11;
int st,ed;
int vis[MAX_N*2];
int d[MAX_N*2];
/*
*/
void bfs(int x)
{
int nx;
vis[x] = 1;
d[x] = 0;
queue<int>q;
q.push(x);
while( q.size() )
{
int s=q.front();
q.pop();
for(int i=1; i<=3; i++ )
{
if( i == 1 )
{
nx = s+1;
}
else if( i == 2 )
{
nx = s-1;
}
else
{
nx = s*2;
}
if( !vis[nx] && nx<=MAX_N && nx>=0 )
{
vis[nx] = 1;
q.push(nx);
d[nx] = d[s]+1;
}
if( nx == ed )
{
printf("%d\n",d[nx]);
return;
}
}
}
}
int main()
{
while( ~scanf("%d%d",&st,&ed))
{
memset(vis, 0, sizeof(vis)); //一定要用 memset 別老用for循環清零 一個是麻煩,第二是容易錯
memset(d, 0, sizeof(d));
if( st == ed )
{
printf("0\n");
continue;
}
bfs(st);
}
return 0;
}
/*
下面附上白皮書上的通用迷宮模板(略典型,思想還是一樣的)
已經加好了註釋:
const int INF = 0x3f3f3f; //沒有到達的地方都是無窮大
typedef pair<int,int> P; //如果量多了可以改成類
char maze[MAX_N][MAX_N+1]; // 存儲字符
int N,M;
int sx,sy; //開始座標
int gx,gy; //結束座標
int d[MAX_N][MAX_N]; //記錄走的步數
int dx[4] = {1,0,-1,0}; //上下左右行走的模擬
int dy[4] = {0,1,0,-1};
int bfs(){
queue<P>que;
for( int i=0; i<N; i++ )
for( int j=0; j<M; j++ )
d[i][j] = INF; //沒有到過的地方全部標記爲無窮大
que.push( P(sx,sy) ); // 把開始座標放入隊列
d[sx][sy] = 0; //並把該點的距離設置爲0;
while( que.front() ){ //判斷隊列是否爲空
p = que.front(); //把隊列的第一個值給 p ;
que.pop(); // 移除
if(P.first == gy && P.second == gy)break;
//如果是到了終點直接退出
for(int i=0; i<4; i++ ){
int nx = P.first + dx[i];
int ny = P.second + dy[i];
//改變座標如果可以走,那麼把新的地址儲存,然後距離加一
if( 0<=nx && nx<N && 0<=ny && ny<M && maze[nx][ny] != '#' && d[nx][ny] == INF){
que.push(P(nx,ny));
d[nx][ny] = d[P.first][P.second] + 1;
}
}
}
}
void solve(){
int res = bfs();
printf("%d\n",res);
}
*/