bfs判重的坑

\(bfs\) 中判重时,应优先在入队时进行判重,而不是在出队时进行判重,因为一个节点 \(u\) 在入队到出队的过程中,可能需要先出队很多其他节点 \(v\),这就会导致其他节点出队且加入新节点的过程中,可能会重复加入多次节点 \(u\),进而导致 \(queue\) 占用的空间过大,最后可能有几个点 \(MLE(Memory Limit Excess)\)

例题
AC代码:在出队时判重

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 40;

int n;
int g[N][N];
bool st[N][N];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

void bfs(int fx, int fy)
{
    typedef pair<int,int> PII;
    bool is_bound = false;
    queue<PII> q;
    vector<PII> node;
    q.push({fx, fy});
    st[fx][fy] = true;  // enqueue check
    while(q.size())
    {
        auto [x, y] = q.front();    q.pop();
        node.push_back({x, y});
        for(int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if(a < 0 || a >= n || b < 0 || b >= n)
            {
                is_bound = true;
                continue;
            }
            if(g[a][b] || st[a][b]) continue;
            q.push({a, b});
            st[a][b] = true; // enqueue check
        }
    }
    if(!is_bound)
        for(auto [a, b] : node)
            g[a][b] = 2;
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++ )    
        for(int j = 0; j < n; j ++ )    cin >> g[i][j];
    
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < n; j ++ )
            if(!g[i][j] && !st[i][j])
                bfs(i, j);
    
    for(int i = 0; i < n; i ++ )    
        for(int j = 0; j < n; j ++ )    cout << g[i][j] << " \n"[j == n - 1];
        
    return 0;
}

MLE代码:出队时判重

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 40;

int n;
int g[N][N];
bool st[N][N];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

void bfs(int fx, int fy)
{
    typedef pair<int,int> PII;
    bool is_bound = false;
    queue<PII> q;
    vector<PII> node;
    q.push({fx, fy});
    while(q.size())
    {
        auto [x, y] = q.front();    q.pop();
        node.push_back({x, y});
        st[x][y] = true;    // dequeue check
        for(int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if(a < 0 || a >= n || b < 0 || b >= n)
            {
                is_bound = true;
                continue;
            }
            if(g[a][b] || st[a][b]) continue;
            q.push({a, b});
        }
    }
    if(!is_bound)
        for(auto [a, b] : node)
            g[a][b] = 2;
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++ )    
        for(int j = 0; j < n; j ++ )    cin >> g[i][j];
    
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < n; j ++ )
            if(!g[i][j] && !st[i][j])
                bfs(i, j);
    
    for(int i = 0; i < n; i ++ )    
        for(int j = 0; j < n; j ++ )    cout << g[i][j] << " \n"[j == n - 1];
        
    return 0;
}
posted @ 2024-03-17 23:26  光風霽月  阅读(2)  评论(0编辑  收藏  举报