bfs 有稳定向下搜索(距离恒定)的特性
常用来求最优解(首解必定最优)
用队列维护搜索可保持其顺序特性
bfs的过程比dfs容易理解的多
在此不做记录
该题单bfs可以过七个点
三个tle
需要优化
仔细推一遍可以发现
每次求得一点的过程中
可以搜到的点反过来也可以搜到该点
他们的最大可走路径值是完全相同的
所以可以记录下来进行记忆化
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e3 + 10;
int map[MAXN][MAXN]; //题图
int dp[MAXN][MAXN]; //图的记忆化
int N, M;
int move[5][2] = {{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1 , 0}}; //移动方向 由题包括本点
int flag[MAXN][MAXN] = {0}; //判重 是否已经搜索过
struct node
{
int x, y;
}a;
struct rec //记录以搜索过的等效位置
{
int x, y;
}brr[MAXN * MAXN];
queue <node> q;
void bfs(node a)
{
if(dp[a.x][a.y])
{
cout<<dp[a.x][a.y]<<endl;
return ;
}
q.push(a);
int ans = 0;
while(!q.empty())
{
a = q.front();
q.pop();
node t;
for(int i = 0; i < 5; i++)
{
t.x = a.x + move[i][0];
t.y = a.y + move[i][1];
if(t.x >= 1 && t.x <= N && t.y >= 1 && t.y <= N && flag[t.x][t.y] == 0 && map[t.x][t.y] + map[a.x][a.y] == 1) //若点a + 点b == 1 则可搜
{
flag[t.x][t.y] = 1;
ans ++;
brr[ans].x = t.x; //记录
brr[ans].y = t.y; //记录
q.push(t);
}
}
}
for(int i = 1; i <= ans; i++) //brr结构体动态更新复用
dp[brr[i].x][brr[i].y] = ans;
ans == 0 ? cout<<1<<endl : cout<<ans<<endl;
}
int main()
{
cin>>N>>M;
string s;
for(int i = 1; i <= N; i++)
{
cin>>s;
for(int j = 0; j < N; j++)
{
map[i][j + 1] = s[j] - '0';
}
}
while(M--)
{
cin>>a.x>>a.y;
//memset(flag, 0, sizeof(flag)); //若不记忆化则需重新标记是否搜过
bfs(a);
}
return 0;
}