若用普通的bfs会tle
解题思路:
先预处理每个点能到的连通图中最多的点
直接输出即可
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010, M = N * N;
int d;//表示当前枚举到了第几个联通图
int ans;
int n, m;
int res[M];//res[connect[i][j]]//表示在connect[i][j]这个连通图中答案是多少
char g[N][N];
int connect[N][N];//(i, j)在connect[i][j]连通图中
int dx[4] = {-1, 1, 0, 0};//枚举四个方向
int dy[4] = {0, 0, -1, 1};
void bfs(int x, int y)
{
queue<PII> q;
q.push({x, y});
connect[x][y] = d;//将x, y加到该连通图中
while (q.size())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i ++ )
{
int a = t.x + dx[i], b = t.y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= n) continue;
if (connect[a][b]) continue;//若已在连通图中
if (g[a][b] == g[t.x][t.y]) continue;//若当前步数与上一步的数字相同
connect[a][b] = d;
ans ++ ;
q.push({a, b});
}
}
ans ++ ;//注意要将原点加上,开始原点直接赋值了
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
if (!connect[i][j])//若(i, j)不在连通图中
{
ans = 0;//记录该连通图中有多少个点
d ++ ;//枚举新的连通图
bfs(i, j);
res[connect[i][j]] = ans;
}
while (m -- )//输出答案
{
int x, y;
scanf("%d %d", &x, &y);
x -- , y -- ;
printf("%d\n", res[connect[x][y]]);
}
return 0;
}