#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<cstring>
#include<cstdio>
#define N 1001
#define LL long long
using namespace std;
bool map[N][N];
//记忆搜索
//(此处说一下,平常写广搜都会定义一个bool vis[N][N]; 然后每执行完一次广搜就会加上一句memset(vis,false,sizeof vis)来初始化,但
//这样既费时也没有太大意义,因为记忆数组remenber里就能代替它的功能,由广搜原理可知,从一个连通图并不能搜到另一个独立的
//连通图,所以只要这个记忆数组就能代替vis[N][N]的全部功能,大大节约了时间)
LL remenber[N][N];
LL ans[N*N]; //储存每个联通块的大小(也就是数量)
int n, m, xxx, yyy;
LL num = 0;//表示第几个联通块
int dx[] = { 1,0,-1,0 };
int dy[] = { 0,1,0,-1 };
struct node //每一个节点用结构体会比较方便
{
int x;
int y;
bool info; //解释一下,这个是每个节点的对应map[x][y]的值
};
LL bfs(int x, int y) //开始广搜
{
//bool vis[N][N];
LL sum = 0;
queue<node>q;
node s;
s.x = x; s.y = y;
sum++; num++;
s.info = map[x][y];
//vis[x][y] = true;
remenber[x][y] = num;
q.push(s);
while (!q.empty())
{
node u;
u = q.front();
q.pop();
for (int i = 0; i < 4; i++)
{
if (u.x + dx[i] < 1 || u.x + dx[i] > n || u.y + dy[i] < 1 || u.y + dy[i] > n || remenber[u.x + dx[i]][u.y + dy[i]]) //判断越界与重复
continue;
node t;
t.x = u.x + dx[i]; t.y = u.y + dy[i]; t.info = map[t.x][t.y];
if (map[u.x][u.y] != map[t.x][t.y])
{
remenber[t.x][t.y] = num;
//vis[t.x][t.y] = true; //以前的错误示范,嗯对,他没用了
sum++;
q.push(t);
}
}
}
ans[num] = sum;
return sum;
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)//输入输出
{
string s;
cin >> s;
for (int j = 1; j <= n; j++)
map[i][j] = s[j - 1] - '0';
}
for (int i = 0; i < m; i++)
{
cin >> xxx >> yyy;
if (!remenber[xxx][yyy])
{
cout << bfs(xxx, yyy) << endl;
//memset(vis, false, sizeof vis); //哈哈哈哈,以前就是这样TLE的呵呵
}
else
cout << ans[remenber[xxx][yyy]] << endl; //直接输出这个联通块对应的值
}
//system("pause");
return 0;
}
P1141 01迷宫 BFS
最新推荐文章于 2024-05-09 19:11:57 发布