zoukankan      html  css  js  c++  java
  • [BFS] [记忆化] [洛谷] P1141 01迷宫

    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;
    }
  • 相关阅读:
    洛谷 P5043 树的同构 题解
    CF 1178E Archaeology 题解
    UVA 1642 MagicalGCD 题解
    洛谷 P3919 可持久化线段树 题解
    SPOJ 4003 Phone List 题解
    OI/ACM最全卡常大招
    洛谷 P3368 树状数组 题解
    逆序对
    洛谷 U78696 图书馆馆长的考验 题解
    原创 疲劳炉石传说
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270570.html
Copyright © 2011-2022 走看看