百练 4116 拯救行动 【bfs的内涵理解】

传送门
//中文题面就不说了.
//提示 : 既然是最短时间, 第一反应肯定是bfs, 但是这道题需要你对bfs的理解要深刻一点. 如果单纯以最短去搜索, 遇到x时间就加2, @就加1, 然后去找. 这样肯定会WA的. 因为这样找只是找到的最短路径下的时间, 并不是最短时间, 所以我们不能以路径来扩充下一个节点, 而是应该以时间来扩充下一个节点, 即队列中推出来的是目前到这个点的最短时间. 所以bfs搜索的最短是要看题目来决定的, 这个要求你要对bfs有一些内涵理解.

AC Code

/** @Cain*/
const int maxn=2e2+5;
char s[maxn][maxn];
bool vis[maxn][maxn];
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int n,m;
int sx,sy;
struct node
{
    int x,y,step;
    node(int x=0,int y=0,int step=0):x(x),y(y),step(step){};
    bool operator < (const node &a) const {
        return a.step < step;
    } //为了保证时间在先出来, 所以我们用优先队列来维护它的优先级.
};
void bfs()
{
    priority_queue<node>q;
    q.push(node{sx,sy,0});
    vis[sx][sy] = true;
    while(!q.empty()){  //除了时间的优先级,其他的跟普通bfs一样的套路.
        node t = q.top();
        q.pop();
        if(s[t.x][t.y] == 'a') {
            printf("%d\n",t.step);
            return ;
        }
        for(int i=0;i<4;i++){
            int xx = t.x + dx[i];
            int yy = t.y + dy[i];
            if(xx<=0 || xx >n || yy<=0 || yy >m || vis[xx][yy]) continue;
            if(s[xx][yy] == '#') continue;
            vis[xx][yy] = true;
            if(s[xx][yy] == 'x') q.push(node{xx,yy,t.step+2});
            else q.push(node{xx,yy,t.step+1});
        }
    }
    printf("Impossible\n");
}
void solve()
{
    scanf("%d%d",&n,&m);
    Fill(s,0);
    for(int i=1;i<=n;i++){
        scanf("%s",s[i]+1);
    }
    Fill(vis,false);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j] == 'r'){
                sx = i;
                sy = j;
            }
        }
    }
    bfs();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值