传送门

最短路好题。


考虑对每个二维坐标建立一个高度属性。

这样每次如果在点(i,j,0)(i,j,0)(i,j,0)只能选择花费bi,jb_{i,j}bi,j​跳向(i,j,ai,j)(i,j,a_{i,j})(i,j,ai,j​),然后如果当前状态的高度不是000就可以花费000的代价选择让高度下降一个,同时向周围四格走一步或者原地不动。

然后跑三次最短路就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=210,M=420;
const ll inf=1e18;
int n,m,K,a[N][N],X1,X2,X3,Y1,Y2,Y3,dx[5]={0,0,1,-1,0},dy[5]={-1,1,0,0,0};
ll dis[N][N][M],len=inf,b[N][N],ltmp,W[3]={0};
bool vis[N][N][M];
string ans="NO";
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
struct Node{
    int x,y,h;
    ll val;
    friend inline bool operator<(const Node&a,const Node&b){return a.val==b.val?a.h>b.h:a.val>b.val;}
};
priority_queue<Node>q;
inline void dijkstra(int sx,int sy,int tx1,int ty1,int tx2,int ty2){
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)for(int k=0;k<=K;++k)dis[i][j][k]=inf,vis[i][j][k]=0;
    while(!q.empty())q.pop();
    q.push((Node){sx,sy,a[sx][sy],dis[sx][sy][a[sx][sy]]=b[sx][sy]});
    while(!q.empty()){
        Node p=q.top();
        q.pop();
        if(vis[X1][Y1][0]&&vis[X2][Y2][0]&&vis[X3][Y3][0])return;
        if(vis[p.x][p.y][p.h])continue;
        vis[p.x][p.y][p.h]=1;
        if(p.h){
            for(int i=0,nx,ny,nh=p.h-1;i<5;++i){
                nx=p.x+dx[i],ny=p.y+dy[i];
                if(!nx||!ny||nx>n||ny>m||vis[nx][ny][nh])continue;
                if(dis[nx][ny][nh]>p.val){
                    dis[nx][ny][nh]=p.val;
                    q.push((Node){nx,ny,nh,p.val});
                }
            }
        }
        else{
            if(dis[p.x][p.y][a[p.x][p.y]]>p.val+b[p.x][p.y]){
                dis[p.x][p.y][a[p.x][p.y]]=p.val+b[p.x][p.y];
                q.push((Node){p.x,p.y,a[p.x][p.y],dis[p.x][p.y][a[p.x][p.y]]});
            }
        }
    }
}
int main(){
    n=read(),m=read(),K=n+m-2;
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)a[i][j]=min(read(),K);
    for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)b[i][j]=read();
    X1=read(),Y1=read(),X2=read(),Y2=read(),X3=read(),Y3=read();
    dijkstra(X1,Y1,X2,Y2,X3,Y3);
    W[1]+=dis[X2][Y2][0],W[2]+=dis[X3][Y3][0];
    dijkstra(X2,Y2,X1,Y1,X3,Y3);
    W[2]+=dis[X3][Y3][0],W[0]+=dis[X1][Y1][0];
    dijkstra(X3,Y3,X1,Y1,X2,Y2);
    W[0]+=dis[X1][Y1][0],W[1]+=dis[X2][Y2][0];
    if(len>W[0])ans="X",len=W[0];
    if(len>W[1])ans="Y",len=W[1];
    if(len>W[2])ans="Z",len=W[2];
    cout<<ans;
    if(len==inf)return 0;
    cout<<'\n'<<len;
    return 0;
}


2018.11.05 bzoj2143: 飞飞侠(最短路)的更多相关文章

  1. BZOJ2143: 飞飞侠

    2143: 飞飞侠 题意: 给出两个 n ∗ m 的矩阵 A,B,以及 3 个人的坐标 在 (i, j) 支付 Ai,j 的费用可以弹射到曼哈顿距离不超过 Bi,j 的位置 问三个人汇合所需要的最小总 ...

  2. BZOJ2143 飞飞侠 & [校内NOIP2018模拟20181026] 最强大脑

    Time Limit: 50 Sec Memory Limit: 259 MB Description 飞飞国是一个传说中的国度,国家的居民叫做飞飞侠.飞飞国是一个N×M的矩形方阵,每个格子代表一个街 ...

  3. 2018.11.05 NOIP模拟 规避(最短路计数)

    传送门 正难则反. 考虑计算两人相遇的方案数. 先正反跑一遍最短路计数. 然后对于一条在最短路上的边(u,v)(u,v)(u,v),如果(dis(s,u)*2<total&&di ...

  4. [BZOJ2143]飞飞侠 并查集优化最短路

    链接 题解 首先很容易想到对每个点暴力跑Dijkstra,但是这样边数是 \(N^4\) 的,考虑优化 发现每次松弛的时候,都要把整个地图扫一遍,每个节点都要重复扫很多次,如果我们在一个点不会再被更新 ...

  5. bzoj千题计划225:bzoj2143: 飞飞侠

    http://www.lydsy.com/JudgeOnline/problem.php?id=2143 分层图最短路 把能够弹跳的曼哈顿距离看做能量 dp[i][j][k]表示在(i,j)位置,还有 ...

  6. 2018.11.05 bzoj3124: [Sdoi2013]直径(树形dp)

    传送门 一道sbsbsb树形dpdpdp 第一问直接求树的直径. 考虑第二问问的边肯定在同一条直径上均是连续的. 因此我们将直径记下来. 然后对于直径上的每一个点,dpdpdp出以这个点为根的子树中不 ...

  7. 2018.11.05 NOIP模拟 相交(dfs序+bit)

    传送门 又TMTMTM考原题真是服. 考虑到两条路径相交一定满足某一条的lcalcalca在另外一条路径上面. 于是分开统计有多少个lcalcalca在当前路径上面以及有多少个路径经过了当前的lcal ...

  8. 2018.11.05 NOIP模拟 列队(差分约束)

    传送门 直接建边跑差分约束就可以了. 代码

  9. 刷题总结——飞飞侠(bzoj2143 最短路)

    题目: Description 飞飞国是一个传说中的国度,国家的居民叫做飞飞侠.飞飞国是一个N×M的矩形方阵,每个格子代表一个街区.然而飞飞国是没有交通工具的.飞飞侠完全靠地面的弹射装置来移动.每个街 ...

随机推荐

  1. f5主备切换演练

    1.准备工作: 1)保证主备机同步 2)备份主备机配置 2.切换:所有操作均在主机 方法1:shutdown主机上联的核心交换机的端口: 此方法在主备切换过程中会丢1个包 方法2:命令行下reboot ...

  2. importlib的用法

    这个模块可以通过字符串导入模块 比如我们有下面的例子 需要导入的模块的代码 在test_import目录下有一个test1的py文件 name = "中国是个大傻逼" class ...

  3. swift4.2 - 一个自定义view弹框

    import UIKit /* * 注册协议view:没找到 UI原图,咱不实现 */ class JYRegisterProtocolView: UIView { /// 点击同意协议的回调 pri ...

  4. [leetcode]210. Course Schedule II课程表II

    There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prereq ...

  5. 组委会正在为美团点评CodeM大赛的决赛设计新赛制

    比赛有 n 个人参加(其中 n 为2的幂),每个参赛者根据资格赛和预赛.复赛的成绩,会有不同的积分.比赛采取锦标赛赛制,分轮次进行,设某一轮有 m 个人参加,那么参赛者会被分为 m/2 组,每组恰好 ...

  6. 【gRPC使用问题4】

    1.进行gRPC服务调用出错:服务不可用 2.解决方案: linux系统部署的节点服务的确不可用,愿意是 系统是泡在虚拟机里面, 计算核数只有一核,太小,服务没有跑起来.

  7. c# 子线程打开子窗体

    下边是在子线程打开子窗口,结果跑到else 里边了跨线程操作窗体控件InvokeRequired失效,无法用于打开子窗体,addonetwo.InvokeRequired,访问不了呢? 大神知道帮忙回 ...

  8. C++中的npos,size_t,size_type

    string类提供了6种查找函数,每种函数以不同形式find命名,这些操作全都返回string::size_type类型的值,以下标形式标记查找匹配所发生的位置,或返回一个名为string::npos ...

  9. visual studio 2017 30天到期,不能输入注册码

    官网下载了visual studio 2017后,第一次安装没有登陆,导致只有30天试用期,虽然还在试用期内,但是无法使用注册码永久使用 解决办法: 1.注册一个微软账号,直接百度搜索“微软账号登陆” ...

  10. PAT 1012 数字分类 (20)(代码+测试点)

    1012 数字分类 (20)(20 分) 给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除的数字中所有偶数的和: A2 = 将被5除后余1的数字按给出顺序进行交错求 ...