BFS+联通块+记忆化搜素【洛谷P1141】

题目链接在此!: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;
}

虽然这种做法比较慢,但是还是过了这道题。

猜你喜欢

转载自blog.csdn.net/KIKO_caoyue/article/details/83181703