BFS TLE求调,已经不会再优化了

P1141 01迷宫

Ascnbeta @ 2024-07-07 15:25:52

基础的BFS,把STL的队列改成手写队列了,搜索结果也另外存储了,不知道还能怎么优化

#include <bits/stdc++.h>
using namespace std;
int n,m,ans;
int mp[1005][1005],a[1005][1005];
bool vis[1005][1005];
int l,r;
struct node {
    int x,y;
}q[1000004];
int dx[5] = {0,1,-1,0,0},dy[5]= {0,0,0,-1,1};
inline void bfs(int x,int y) {
    ++ans;
    vis[x][y] = true;
    q[r++] = node{x,y};
    while(!(l == r)) {
        node t = q[l];
        ++l;
        for (int i = 1; i <= 4; i++) {
            int tx =t.x +dx[i],ty = t.y+dy[i];
            if (tx < 1 || ty < 1 || tx > n || ty > n) continue;
            if (mp[tx][ty] == mp[t.x][t.y]) continue;
            if (vis[tx][ty]) continue;
            vis[tx][ty] = true;
            if (a[tx][ty] != 0) {
                ans += a[tx][ty];
                continue;
            }
            ++ans;
            q[r++] = node{tx,ty};
        }
    }
}
int main () {
    cin >> n >> m;
    for (int i = 1; i <= n ;i++) {
        for (int j = 1; j <= n; j++) {
            char c;
            cin >> c;
            mp[i][j] =c - '0';
        }
    }

    while (m--) {
        int x,y;
        cin >> x >> y;
        if (a[x][y] != 0 ) {
            cout << a[x][y] << endl;
            continue;
        }
        ans = 0;
        memset(vis,0,sizeof(vis));
        memset(q,0,sizeof(q));
        l = 0,r = 0;
        bfs(x,y);
        for (int i = 0; i <= r; i++) {
            if (a[q[i].x][q[i].y] == 0) a[q[i].x][q[i].y] = ans;
        }
        cout << ans << endl;
    }
    return 0;
}

by Ascnbeta @ 2024-07-07 15:27:27

80pts TLE on #3 #11


by do_it_tomorrow @ 2024-07-07 15:27:42

@AlwaysSunshine 您不会先预处理吗?


by do_it_tomorrow @ 2024-07-07 15:29:26

其实记录一下已经算出来的答案也可以啊。


by Ascnbeta @ 2024-07-07 15:30:43

@do_it_tomorrow

for (int i = 0; i <= r; i++) {
            if (a[q[i].x][q[i].y] == 0) a[q[i].x][q[i].y] = ans;
        }
        cout << ans << endl;

这是把已经算好的答案存储的代码

预处理真没想到,我去写写


by do_it_tomorrow @ 2024-07-07 15:41:43

@AlwaysSunshine 我的意思是您一边 bfs 一边存答案。


by I_Love_DS @ 2024-07-07 15:53:26

连通块? @AlwaysSunshine


by Ascnbeta @ 2024-07-07 16:10:31

@do_it_tomorrow 我刚开始用预处理来标记当前位置对应的连通块也没过,但我发现删了这一行:

memset(q,0,sizeof(q));

就能过了! 然后我就把我现在这个代码的

memset(vis,0,sizeof(vis));
memset(q,0,sizeof(q));

也删了,发现也不会TLE了

memset的常数这么大么


by Ascnbeta @ 2024-07-07 16:11:00

相当于memset导致了TLE


|