题解 | #迷宫2#

迷宫2

https://ac.nowcoder.com/acm/problem/15196

思路

题意:求 让蜥蜴没办法达到终点所必须花费的最小总代价
我们通过 把特殊的走道转化为墙壁( 转换代价为g[i][j] ),来使蜥蜴最终无法到达终点

g[i][j]取不同值的意义:-1代表墙壁,0代表走道,而1到10^9之间的正整数代表特殊的走道。
因为 g[i][j] = -1 代表已经是墙壁,故转换代价为 0,因此我们让 g[i][j] = -1的,g[i][j] = 0
而g[i][j] = 0 的 代表无法转换为墙壁,故代价是无穷大,因此我们让 g[i][j] = 0的,g[i][j] = 1e18

因为 蜥蜴在左上角,终点在右下角,要使得蜥蜴无法到达终点 就必须 有 ''一道墙'' 把蜥蜴或者终点给围起来

围墙的位置 有以下四种情况:

到这里,问题便转换为了 建造一面最小花费的围墙,围墙的情况或格式只有四种 :见上面图片

我们用 堆优化dijkstra 来解决问题:

① 所有可能的起点入队 ,起点:围墙的头部 
在这里我们规定 头部要么在上端,要么在右端,则尾部 要么在下端,要么在左端

② 弹出最小花费的点 ,用该点更新 到其后继点的最小花费
若弹出的点 可能作为围墙尾部(在左端或者在下端),用到该点的最小花费,来更新最终答案

③ 后继点入队

综上,Code 如下 .

Code

#include <bits/stdc++.h>

using namespace std;

const int N = 510;

typedef long long ll;

struct node{
    int x,y;
    ll w;
    bool operator < (const node &x) const{
        return w > x.w;
    }
};
int rou[4][2]={-1,0,0,1,1,0,0,-1};
bool st[N][N];
ll g[N][N];
int T,n,m;

int main(){
    cin>>T>>n>>m;

    while(T--){
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {
          cin>>g[i][j];
          if(g[i][j]==0) g[i][j]=1e18;
          else if(g[i][j]==-1) g[i][j]=0;  
          st[i][j]=false;
        }        

        priority_queue<node>q;
        for(int j=2;j<=m;j++) if(g[1][j]!=1e18) q.push({1,j,g[1][j]}) ;
        for(int i=2;i<n;i++) if(g[i][m]!=1e18) q.push({i,m,g[i][m]}) ;

        ll res=1e18;
        while(q.size()){
            auto p=q.top();
            q.pop();
            int x=p.x,y=p.y;
            ll w=p.w;        
            if(y==1||x==n) {
                 res=min(res,w);  //弹出来的一定是最短的边 也即是最小花费的边
                 continue;   
             }

            if(st[x][y]) continue;

            st[x][y]=true;
            for(int i=0;i<4;i++){
                int xi=x+rou[i][0];
                int yi=y+rou[i][1];
                if(xi<1||xi>n||yi<1||yi>m||g[xi][yi]==1e18) continue;
                q.push({xi,yi,w+g[xi][yi]});
            }
        }

        if(res==1e18) puts("-1");
        else cout<<res<<endl;
    }

    return 0;
}
全部评论
https://paste.liumingye.cn/4804 能请教一下我的代码哪里写错了吗😵
点赞 回复 分享
发布于 2022-02-07 14:52
大佬的题解让我醍醐灌顶
点赞 回复 分享
发布于 2021-12-06 15:24

相关推荐

最近群里有很多同学找我看简历,问问题,主要就是集中在明年三月份的暑期,我暑期还能进大厂嘛?我接下来该怎么做?对于我来说,我对于双非找实习的一个暴论就是title永远大于业务,你在大厂随随便便做点慢SQL治理加个索引,可能就能影响几千人,在小厂你从零到一搭建的系统可能只有几十个人在使用,量级是不一样的。对双非来说,最难的就是约面,怎么才能被大厂约面试?首先这需要一点运气,另外你也需要好的实习带给你的背书。有很多双非的同学在一些外包小厂待了四五个月,这样的产出有什么用呢?工厂的可视化大屏业务很广泛?产出无疑是重要的,但是得当你的实习公司到了一定的档次之后,比如你想走后端,那么中厂后端和大厂测开的选择,你可以选择中厂后端(注意,这里的中厂也得是一些人都知道的,比如哈啰,得物,b站之类,不是说人数超过500就叫中厂),只有这个时候你再去好好关注你的产出,要不就无脑大厂就完了。很多双非同学的误区就在这里,找到一份实习之后,就认为自己达到了阶段性的任务,根本不再投递简历,也不再提升自己,玩了几个月之后,美其名曰沉淀产出,真正的好产出能有多少呢?而实际上双非同学的第一份实习大部分都是工厂外包和政府外包!根本无产出可写😡😡😡!到了最后才发现晚了,所以对双非同学来说,不要放过任何一个从小到中,从中到大的机会,你得先有好的平台与title之后再考虑你的产出!因为那样你才将将能过了HR初筛!我认识一个双非同学,从浪潮到海康,每一段都呆不久,因为他在不断的投递和提升自己,最后去了美团,这才是双非应该做的,而我相信大部分的双非同学,在找到浪潮的那一刻就再也不会看八股,写算法,也不会打开ssob了,这才是你跟别人的差距。
迷茫的大四🐶:我也这样认为,title永远第一,只有名气大,才有人愿意了解你的简历
双非本科求职如何逆袭
点赞 评论 收藏
分享
评论
8
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务