简单BFS

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用递归

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值