BFS就是用队列完成,每一次push,pop
P1135
这道题可以广搜,也可以用dp
广搜的思路其实就是每一次出队自己,然后入队上下的楼梯,要设置两个队列,然后记得flag,一开始入队
#include<iostream>
using namespace std;
int a[202],f[202][202];
int main()
{
int N,A,B,iflag=0;
cin>>N>>A>>B;
for(int i=1;i<=N;i++)
{
cin>>a[i];
}
if(A==B)
{
cout<<0;
return 0;
}
f[0][A]=1;
for(int i=0;i<=200;i++)
for(int j=1;j<=N;j++)
{
if(f[i][j])
{
if(j+a[j]<=N)
f[i+1][j+a[j]]=1;
if(j-a[j]>=1)
f[i+1][j-a[j]]=1;
if(f[i+1][B]==1)
{cout<<i+1;
iflag=1;
return 0;
}
}
}
if(iflag==0)
cout<<-1;
return 0;
}
-----------------------------------
#include<iostream>
#include<queue>
using namespace std;
int N,A,B;
int visited[202],cnt=0,a[202],flag;
queue<int>Q;
queue<int>P;
void bfs(int o,int b)
{
int dx,dy;
while(!Q.empty() )
{
if(dx==B||dy==B)
{ cout<<cnt;
flag=1;
return ;
}
if(Q.front() +P.front() <=N)
{
dx=Q.front() +P.front() ;
if(!visited[dx])
{
visited[dx]=1;
Q.push(dx);
P.push(a[dx]);
cnt++;
}
}
if(Q.front() -P.front() >=1)
{
dy=Q.front() -P.front() ;
if(!visited[dy])
{
visited[dy]=1;
Q.push(dy);
P.push(a[dy]);
cnt++;
}
}
Q.pop() ;
P.pop() ;
}
if(flag==0)
cout<<-1;
}
int main()
{
cin>>N>>A>>B;
if(A==B)
{cout<<0;
return 0;
}
for(int i=1;i<=N;i++)
{
cin>>a[i];
}
visited[A]=1;
Q.push(A);
P.push(a[A]);
bfs(A,a[A]);
}
``P1162
这题目本来想着循环,但或许有奇形怪状的环,所以广搜最好,然后还有就是说最好外面搞一圈虚拟的零,这样就可以把他们连起来然后打上标记,那些又是零又没有被打上标记的就变成2
```cpp
#include<iostream>
#include<queue>
using namespace std;
queue <int> x;
queue <int> y;
int xx[]={1,0,-1,0};//方向
int yy[]={0,-1,0,1};
int vis[31][31]={0};//标记
int a[31][31];
int m,dx,dy;
int main()
{
cin>>m;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
}
}
x.push(0);//第一个位置先放入队列
y.push(0);
a[0][0]=0;
while(!x.empty() )//开始不为空的广搜
{
for(int i=0;i<4;i++)
{
dx=x.front() +xx[i];
dy=y.front() +yy[i];//就是旁边各个方向
if(dx>=0&&dx<=m+1&&dy>=0&&dy<=m+1&&a[dx][dy]==a[x.front() ][y.front() ]&&!vis[dx][dy])
{
x.push(dx);
y.push(dy);
vis[dx][dy]=1;//入队打标记
}
}
x.pop() ;
y.pop() ;
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]==0&&vis[i][j]==0)
{
a[i][j]=2;
}
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
P1443
或许马走的比较复杂,但基本差不多,每多一次广搜要记录一下那个数字
#include<iostream>
#include<queue>
#include<cstring>//memset要用到
using namespace std;
int xx[]={-2,-2,-1,-1,1,1,2,2};
int yy[]={1,-1,2,-2,2,-2,1,-1};
struct Node
{
int x;
int y;
int t;//用来记录次数
};
queue <Node> Q;
int n,m,qi,zh,dx,dy;
int vis[401][401];
int main()
{
cin>>n>>m;
cin>>qi>>zh;
Q.push((Node){qi,zh,0});
memset(vis,-1,sizeof(vis));//没有过的最后就自动-1
vis[qi][zh]=0;
while(!Q.empty() )
{
for(int i=0;i<=7;i++)
{
int dx=xx[i]+Q.front().x;
int dy=yy[i]+Q.front().y;
if(dx>=1&&dx<=n&&dy>=1&&dy<=m&&vis[dx][dy]==-1)
{
vis[dx][dy]=Q.front().t+1;
Q.push((Node){dx,dy,Q.front().t+1});//直接进入整个结构体
}
}
Q.pop();
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%-5d ",vis[i][j]) ;
}
cout<<endl;
}
return 0;
}
P1141
有亿点点烦,首先你得进行广搜,直到搜不到为止,然后他们相通,其中每一个赋值相同,不同的是数字不同的colour,就可以直接用来标记是否有过搜索,cnt用来记录查询的数字,每出去一个就+1
#include<iostream>
#include<queue>
using namespace std;
int xx[]={1,0,-1,0};
int yy[]={0,1,0,-1};
int vis[1001][1001]={0},colour=0,dx,dy,m,cnt,n;
int ans[1000];
int mp[1001][1001]={0};
void bst(int i,int j)
{
queue<int>x;
queue<int>y;
x.push(i);
y.push(j);
vis[i ][j ]=colour;//每一次搜索的colour相同,所以colour要放在外面
while(!x.empty())
{
for(int i=0;i<=3;i++)
{
dx=x.front() +xx[i];
dy=y.front() +yy[i];
if(dx>=1&&dx<=m&&dy>=1&&dy<=m&&!vis[dx][dy]&&mp[dx][dy]!=mp[x.front()][y.front()])
{
vis[dx][dy]=colour;
x.push(dx);
y.push(dy);
}
}
x.pop() ;
y.pop() ;
cnt++;///cnt的位置
}
}
int main()
{
char c;
cin>>m>>n;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
cin>>c;
if(c=='1')
mp[i][j]=1;
if(c=='0')
mp[i][j]=0;
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
if(!vis[i][j])
{
++colour;
bst(i,j);
ans[colour]=cnt;//colour就是vis[i][j]所以未来出答案可以用坐标
cnt=0;
}
}
for(int i=1;i<=n;i++)
{
int hx,hy;
cin>>hx>>hy;
cout<<ans[vis[hx][hy]]<<endl;
}
}
P4017
其实就是从最牛逼的和最垃圾的开始寻找彼此,不断入队和自己相连的,定p找i然后直达找到彼此,最后找到返回1
#include<iostream>
using namespace std;
int r[5005];
int mp[5005][5005],nb[5005],sb[5005],m,n,ans=0;
int dfs(int p)
{
if(!nb[p])
{
return 1;
}
if(r[p]) return r[p];
int sum=0;
for(int i=1;i<=m;i++)
{
if(mp[i][p])
{
sum=(sum+dfs(i))%80112002;
}
}
return r[p]= sum;
}
int main()
{
cin>>m>>n;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
mp[x][y]=1;
sb[x]++;
nb[y]++;
}
for(int i=1;i<=m;i++)
{
if(sb[i]==0)
ans=(ans+dfs(i))%80112002;
}
cout<<ans;
return 0;
}
啊这上面的是深搜
#include<bits/stdc++.h>
using namespace std;
queue<int>q;
int n,m;
int chu[5005],ru[5005],mp[5005][5005],f[5005]={0},c;
int i,j,a,b,ans=0;
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>a>>b;
mp[a][b]=1;
ru[a]++;
chu[b]++;
}
for(int i=1;i<=n;i++)
{
if(chu[i]==0)
{
f[i]=1;
q.push(i);
}
}
while(!q.empty())
{
c=q.front();
q.pop();
for(int k=1;k<=n;k++)
{ if(mp[c][k]==0) continue;
if (mp[c][k]==1)
{
f[k]+=f[c];
f[k]%=80112002;
chu[k]--;
if(chu[k]==0)
{
if(ru[k]==0)//就是最终极的那个
{
ans+=f[k];
ans%=80112002;
continue;
}
q.push(k);
}
}
}
}
cout<<ans;
}
真没啥差别,就使用了队列,dfs用递归