BFS 题目 总结
首先介绍 一下BFS 和 DFS 之间的区别
首先 上图
这个图 如果 用 DFS 搜索的应该是 从 根节点 1 开始 然后沿着 从左向右 将 每个分支 搜索到底 比如 搜索到 5这个节点时
就是 5-->9 然后回去 再 5-->10 -->14再回去 10-->15 再回去 将每个分支搜索完毕
用 BFS的话 也是 从 更节点开始搜索但是 BFS 要 通过 一个叫队列 的 东西
队列 是一个先进先出的类似于数组的数据结构 但是是很简单 的
queue<数据类型>变量名 这就是一个简单的定义
BFS的搜索顺序 是将 靠近这个节点且距离相等的点 搜索完毕 这里需要标记一下 该节点是否在队列里面 这个图的搜索顺序是从1开始 然后依次到达 15;
接下来是几个例题 关于BFS的
第一个 PO 2251 点这里 http://poj.org/problem?id=2251
这是一个 有六条路径的类似于迷宫的BFS
Source Code
Problem: 2251 User: rg180120
Memory: 856K Time: 47MS
Language: G++ Result: Accepted
Source Code
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct Node
{
int x,y,z;
int len;
};
Node c,d;
char a[35][35][35];
int b[35][35][35];
int L,R,C;
int f[3][6]={{1,-1,0,0,0,0},
{0,0,1,-1,0,0},
{0,0,0,0,1,-1}};
int s2[35][35][35];
int flag;
int si,sj,sk;
bool pop(int x,int y,int z)
{
return (x>=1&&x<=L&&y>=1&&y<=R&&z>=1&&z<=C);
}
int bfs(int si,int sj,int sk)
{
queue<Node>s;
c.x=si;
c.y=sj;
c.z=sk;
c.len=0;
s.push(c);
while(!s.empty())
{
d=s.front();
s.pop();
c.len=d.len+1;
for(int i=0;i<6;i++)
{
c.x=d.x+f[0][i];
c.y=d.y+f[1][i];
c.z=d.z+f[2][i];
if(pop(c.x,c.y,c.z)&&!b[c.x][c.y][c.z]&&a[c.x][c.y][c.z]!='#')
{
if(a[c.x][c.y][c.z]=='E')
return c.len;
b[c.x][c.y][c.z]=1;
s.push(c);
}
}
}
return -1;
}
int main()
{
while(cin>>L>>R>>C)
{
if(!L&&!R&&!C) break;
memset(b,0,sizeof(b));
for(int i=1;i<=L;i++)
{
for(int j=1;j<=R;j++)
{
for(int k=1;k<=C;k++)
{
cin>>a[i][j][k];
if (a[i][j][k]=='S')
{
si=i;
sj=j;
sk=k;
}
}
}
}
flag=bfs(si,sj,sk);
if (flag==-1)
cout << "Trapped!" << endl;
else
cout << "Escaped in " << flag << " minute(s)." << endl;
}
return 0;
}
下一道 点这里 POJ3278 http://poj.org/problem?id=3278
这道题目的意思是 从N 点到K点 可以 通过向前一步 即为在这个数轴上加一 还有向后一步 即为减一
还有一个是向前走到2倍的位置如 从4到8 ,这三种方式每进行一步耗时都为一秒, 怎么通过这三种方式到达K点最快
Source Code
Problem: 3278 User: rg180120
Memory: 1512K Time: 32MS
Language: G++ Result: Accepted
Source Code
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
const int maxn=100000;
typedef long long ll;
int n,k;
int ans;
int vis[maxn+7];
int dis[maxn+7];
queue<int>s;
int bfs(int n)
{
int head,next;
s.push(n);
dis[n]=0;
vis[n]=1;
while(!s.empty())
{
head=s.front();
s.pop();
for(int i=1;i<=3;i++)
{
if(i==1)
next=head+1;
else if(i==2)
next=head-1;
else if(i==3)
next=head*2;
if(next<0 || next>maxn) continue; //排除出界情况
if(!vis[next])
{
vis[next]=1;
dis[next]=dis[head]+1;
s.push(next);
}
if(next==k)
return dis[next];
}
}
return -1;
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
while(!s.empty()) s.pop();
ans=bfs(n);
cout<<ans<<endl;
}
}
再来一道 POJ 1426 http://poj.org/problem?id=1426
这道题目 是非常有意思的题目 意思大体是说 给你一个数 找到 这个数的一个倍数光有1和0组成 答案有多个 每个数输出一个 就行 这道题 一上来看起来和BFS没大有关系 然后你仔细 想 是不是 相当于 从1开始的有两条路一个是*10一个数是*10+1;那么这样
就是一个典型的BFS题目的 代码是非常简单的
Source Code
Problem: 1426 User: rg180120
Memory: 5000K Time: 438MS
Language: G++ Result: Accepted
Source Code
#include<cstdio>
#include<iostream>
#include <algorithm>
#include<queue>
using namespace std;
typedef long long ll;
queue<ll>s;
ll d;
ll temp1,temp2;
int n;
void bfs()
{
s.push(1);
while(!s.empty())
{
d=s.front();
s.pop();
if(d%n==0)
{
cout<<d<<endl;
return ;
}
else
{
temp1=d*10;
temp2=d*10+1;
s.push(temp1);
s.push(temp2);
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
bfs();
while(!s.empty()) s.pop();
}
return 0;
}
还有一个 POJ 3126 http://poj.org/problem?id=3126
这道题目 是说 给你一个T;表示有T组输入 然后 每组两个4位数的素数的数据 N,,M; 意思是 将N变成M每次 只能改变一位数且每次改变位到应该是素数然后从N最短需要几步到M 首先对这个题目需要先打表 主要将 1000到10000的素数标记出来
然后分别对每位数据进行 操作
Source Code
Problem: 3126 User: rg180120
Memory: 764K Time: 16MS
Language: G++ Result: Accepted
Source Code
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=10030;
struct Node
{
int date;
int len;
};
int t,n,m;
int vis[maxn+7];
int isprime[maxn+7];
void prime()
{
memset(isprime,0,sizeof(isprime));
for(int i=2;i<=maxn;i++)
{
if(!isprime[i])
for(int j=i*2;j<=maxn;j+=i)
isprime[j]=1;
}
}
Node w,l;
queue<Node>q;
void bfs(int n,int m)
{
vis[n]=1;
l.date=n;
l.len=0;
q.push(l);
while(!q.empty())
{
l=q.front();
q.pop();
// cout<<l.date<<endl;
if(l.date==m)
{
cout<<l.len<<endl;
return ;
}
for(int i=1;i<=9;i++) //个
{
int s=l.date/10*10+i;
if(!vis[s]&&!isprime[s])
{
vis[s]=1;
w.date=s;
w.len=l.len+1;
q.push(w);
}
}
for(int i=0;i<=9;i++) //十
{
int s=l.date/100*100+l.date%10+i*10;
if(!vis[s]&&!isprime[s])
{
vis[s]=1;
w.date=s;
w.len=l.len+1;
q.push(w);
}
}
for(int i=0;i<=9;i++) //百
{
int s=l.date/1000*1000+l.date%100+i*100;
if(!vis[s]&&!isprime[s])
{
vis[s]=1;
w.date=s;
w.len=l.len+1;
q.push(w);
}
}
for(int i=1;i<=9;i++) //千
{
int s=l.date%1000+i*1000;
if(!vis[s]&&!isprime[s])
{
vis[s]=1;
w.date=s;
w.len=l.len+1;
q.push(w);
}
}
}
// cout<<"Impossible"<<endl;
}
int main()
{
cin>>t;
prime();
while(t--)
{
cin>>n>>m;
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
bfs(n,m);
}
return 0;
}
上一篇: 广度优先搜索(BFS)C++
下一篇: Vue.js每天必学之方法与事件处理器