洛谷P1141 01迷宫(鶸的第一篇博客(害

可能是最近把搜索题单AK了(这里强推luogu题单,之前一直对搜索很没理解,做了这些题 感觉悟了不少),然后智能推荐就给我推了这道01迷宫pwq,看到普及-和"迷宫",好家伙,我感觉我又可以了,于是开始了大清早到机房的第一道题目。


洛谷P1141 01迷宫

原题目链接

题面

题目描述
有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。

你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

输入格式
第1行为两个正整数n,m。

下面n行,每行n个字符,字符只可能是0或1,字符之间没有空格。

接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。

输出格式
m行,对于每个询问输出相应答案。

输入输出样例
输入
2 2
01
10
1 1
2 2
输出
4
4
说明/提示
所有格子互相可达。

数据范围
n≤1000,m≤100000n≤1000,m≤100000。

//开始正文

//看到这道题,我们首先看数据范围 首先是1000* 1000的图,那么我先想到的就是宽搜(因为我更会宽搜一点点),然后再看这道题很显然是求连通块。

//然后开始敲 (CE了一发index这个变量名会ce的啊啊啊

//然后1A了

//1A==水题

//话不多说 直接上代码你明明废话很多欸

ACcode 686ms / 10.01MB
#include 

using namespace std;

int a[1010][1010];//存图
int vis[1010][1010];//标记每个点所在连通块的数字
int ans[1000*1000+1000];//存每个连通块的答案
int n,m;

struct node {
     
	int x,y;
};
int sx,sy;
queue<node>q;
int index1;
int walk[4][2]={
     {
     1,0},{
     -1,0},{
     0,1},{
     0,-1}};
void bfs(){
     
	node tmp={
     sx,sy};//未被访问过的连通块的点 入队 
	q.push(tmp);
	int cnt=1;//记录该连通块内格子个数 
	vis[sx][sy]=index1;//连通块的起点序号标记 
	while(!q.empty()){
     
		node u=q.front();q.pop();//前继状态 
		for(int k=0;k<=3;k++){
     //后继状态(前继状态的扩展点) 
			int dx=u.x+walk[k][0],dy=u.y+walk[k][1];
			if(dx<1||dx>n||dy<1||dy>n||vis[dx][dy]!=0||(a[dx][dy]+a[u.x][u.y]!=1)){
     
// 如果超出边界 肯定要被t掉 如果访问的时候人家已经有了联通的块 那就t了 
//题意 0 1 0 1 这样组成的才是联通的 那么前继节点和后继节点的和必然得是1 如果不是就跳过 
				continue;
			}
			vis[dx][dy]=index1;//把后继节点归属的连通块序号打上标记 
			node tmp={
     dx,dy};//后继节点入队 作为别人的前继节点 
			q.push(tmp);
			cnt++;
		}
		ans[index1]=cnt;//记录同一联通序号的节点的联通块格子个数 
	}
}
int main(){
     
	cin>>n>>m;
	index1=0;//使联通块序号从1开始 
	for(int i=1;i<=n;i++){
     
		for(int j=1;j<=n;j++){
     
			scanf("%1d",&a[i][j]);//数字读入法,蛮好用的(雾
		}
	}
	memset(vis,0,sizeof(vis));
	while(m--){
     
		int x,y;cin>>x>>y;
		if(vis[x][y]==0){
     //如果没被标记就bfs(); 
			index1++;
			sx=x;sy=y;
			bfs();
//Debug用			cout<<"index=="<
//Debug用			cout<<"index:"<
			cout<<ans[vis[x][y]]<<endl; 
		}
		else cout<<ans[vis[x][y]]<<endl;
	}
	return 0;
}

你可能感兴趣的:(洛谷刷题记,bfs)