题目链接在此!:https://www.luogu.org/problemnew/show/P1141
首先提一下,这个题目就是很简单的BFS,dalao们的并查集我也没看懂(我蒻),直接写BFS肯定是会T的,因为每一个搜图都会有很多重复的地方被搜到了。
下面说思路:在这个图中,很明显就是一些联通块,每一个块里面的每一个坐标的答案都是一样的。那么我们就直接把搜过的地方的每一个坐标都记录下来,然后这些坐标的值全部都是一样的。
直接上代码比较清晰:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
const int maxn = 1010;
int G[maxn][maxn];
bool vis[maxn][maxn];
int ans[maxn][maxn];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int cnt = 1;
void init()
{
memset(G,0,sizeof(G));
memset(ans,0,sizeof(ans));
memset(vis,0,sizeof(vis));
}
vector<pair<int,int> > asked;
int n,m;
void bfs(int x,int y)
{
queue<pair<int,int> >q;
q.push(P(x,y));
vis[x][y] = true;
asked.push_back(P(x,y));
while(!q.empty())
{
int nx = q.front().first;
int ny = q.front().second;
q.pop();
for(int i=0;i<4;i++)
{
int nowx = nx+dx[i];
int nowy = ny+dy[i];
if(G[nx][ny] + G[nowx][nowy] == 1 && !vis[nowx][nowy] && nowx>=1 && nowx<=n && nowy>=1 && nowy<=n)
{
vis[nowx][nowy] = true;
cnt++;
asked.push_back(P(nowx,nowy));
q.push(P(nowx,nowy));
}
}
}
}
int main()
{
while(cin>>n>>m)
{
init();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
char ch;
cin>>ch;
G[i][j] = ch-'0';
}
}
for(int i=0;i<m;i++)
{
cnt = 1;
int x,y;
scanf("%d%d",&x,&y);
if(!vis[x][y])
{
bfs(x,y);
for(int i=0;i<asked.size();i++)
{
ans[asked[i].first][asked[i].second] = cnt;
}
cout<<ans[x][y]<<endl;
asked.clear();
}
else
{
cout<<ans[x][y]<<endl;
}
}
}
return 0;
}
虽然这种做法比较慢,但是还是过了这道题。