63分,后5个点MLE求助!

P2895 [USACO08FEB] Meteor Shower S

danlao @ 2024-02-01 10:15:11

记录

#include <iostream>
#include <queue>
using namespace std;
#define hh printf("\n")
#define kg printf(" ")
#define cg ch=getchar()
inline int read(){
    int x=0,f=1;char cg;
    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;cg;}
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';cg;}
    return x*f;
}
inline void write(int x){
    if(x<0){putchar('-');x=-x;}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
int dx[5]={0,-1,0,1,0};
int dy[5]={0,0,-1,0,1};
int n,map[510][510],maxt,inf=2147483647;
bool vis[510][510];
struct csp{
    int x,y,t;
};
int bfs(int x,int y,int t){
    queue<csp>q;
    q.push((csp){x,y,t});
    while(!q.empty()){
        x=q.front().x;
        y=q.front().y;
        t=q.front().t;
        q.pop();
        vis[x][y]=1;
        if(map[x][y]==inf) return t;
        for(int i=1;i<=4;i++){
            int tx=x+dx[i];
            int ty=y+dy[i];
            if(tx>=0&&ty>=0&&tx<=500&&ty<=500&&!vis[tx][ty]&&map[tx][ty]>t+1) q.push((csp){tx,ty,t+1});
        }
    }
    return -1;
}
int main(){
    for(int i=0;i<=500;i++)
        for(int j=0;j<=500;j++)
            map[i][j]=inf;
    n=read();
    for(int i=1;i<=n;i++){
        int x=read(),y=read(),t=read();
        map[x][y]=min(map[x][y],t);
        maxt=max(maxt,t);
        for(int j=1;j<=4;j++){
            int tx=x+dx[j];
            int ty=y+dy[j];
            if(tx>=0&&ty>=0) map[tx][ty]=min(map[tx][ty],t);
        }
        if(!map[0][0]) {
            write(-1);
            return 0;
        }
    }
    write(bfs(0,0,0));
    return 0;
}

by jkfof @ 2024-02-21 13:54:27

把vis[tx][ty]=1加在bfs里的push()后面,就是那个很长的判断后面,然后可以把上面的vis[x][y]=1;删去。

因为通过计算得,如果是vis[x][y]=1;这样的写法,会导致同一个位置多次push,而且push的次数会随m变大而变大。


by jkfof @ 2024-02-21 14:10:05

@jkfof 说错了,不是m,是bfs的范围


by Ruru_Saika @ 2024-09-03 23:56:12

帮大忙了,谢谢佬


|