2143: 飞飞侠

题意:

给出两个 n ∗ m 的矩阵 A,B,以及 3 个人的坐标

在 (i, j) 支付 Ai,j 的费用可以弹射到曼哈顿距离不超过 Bi,j 的位置

问三个人汇合所需要的最小总费用

其中 0 < n,m < 150,0 < A < 1000,0 < B < 10^9。


分层图最短路也好,用dijkstra/spfa做dp也罢,反正就是辣么一回事!

把距离等效成油量之类的东西,单独拿出一维

\(f_{i,j,k}\)表示从起点到(i,j),剩下k个油的最小费用

枚举移动和换油(不是加油)来转移

因为不是dag所以用dijkstra来做

spfa应该也可以,不过这是个满足最短路性质的dp没必要用spfa

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define fir first
#define sec second
const int N = 152; int n, m, a[N][N], b[N][N];
struct meow {
int x, y, c, d;
bool operator < (const meow &r) const {
return d > r.d;
}
meow(int a1=0, int a2=0, int a3=0, int a4=0):x(a1), y(a2), c(a3), d(a4){}
} ;
meow a1, a2, a3; inline bool valid(int x, int y) {
return 1<=x && x<=n && 1<=y && y<=m;
}
int d[N][N][305];
bool vis[N][N][305];
priority_queue<meow> q;
int dx[10] = {1, -1, 0, 0}, dy[10] = {0, 0, 1, -1};
int ans[5][5];
int flag[N][N];
void dij(meow s) {
memset(flag, 0, sizeof(flag));
memset(d, 127, sizeof(d));
memset(vis, 0, sizeof(vis));
int x = s.x, y = s.y;
d[x][y][0] = 0;
q.push(meow(x, y, 0, 0));
while(!q.empty()) {
//if(vis[a2.x][a2.y][0] && vis[a3.x][a3.y][0] && vis[a1.x][a1.y][0]) break;
if(flag[a1.x][a1.y] && flag[a2.x][a2.y] && flag[a3.x][a3.y]) break;
meow u = q.top(); q.pop();
int x = u.x, y = u.y, c = u.c;
if(vis[x][y][c]) continue;
vis[x][y][c] = 1;
flag[x][y] = 1; int &t = d[x][y][b[x][y]];
if(t > d[x][y][c] + a[x][y] && b[x][y] > c) {
t = d[x][y][c] + a[x][y];
q.push(meow(x, y, b[x][y], t));
}
if(c) for(int i=0; i<5; i++) {
int tx = x + dx[i], ty = y + dy[i];
if(!valid(tx, ty)) continue;
int &t = d[tx][ty][c-1];
if(t > d[x][y][c]) {
t = d[x][y][c];
if(!vis[tx][ty][c-1]) q.push(meow(tx, ty, c-1, t));
}
} /*else {
int &t = d[x][y][b[x][y]];
if(t > d[x][y][c] + a[x][y]) {
t = d[x][y][c] + a[x][y];
q.push(meow(x, y, b[x][y], t));
}
}
*/
}
while(!q.empty()) q.pop();
}
int main() {
freopen("in", "r", stdin);
ios::sync_with_stdio(false); cin.tie(); cout.tie();
cin >> n >> m;
for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) cin >> b[i][j], b[i][j] = min(b[i][j], 300);
for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) cin >> a[i][j]; cin >> a1.x >> a1.y >> a2.x >> a2.y >> a3.x >> a3.y; memset(ans, 127, sizeof(ans));
dij(a1);
for(int k=0; k<=300; k++) {
ans[1][2] = min(ans[1][2], d[a2.x][a2.y][k]);
ans[1][3] = min(ans[1][3], d[a3.x][a3.y][k]);
} //cout << ans[1][2];
//return 0; dij(a2);
for(int k=0; k<=300; k++) {
ans[2][1] = min(ans[2][1], d[a1.x][a1.y][k]);
ans[2][3] = min(ans[2][3], d[a3.x][a3.y][k]);
}
dij(a3);
for(int k=0; k<=300; k++) {
ans[3][2] = min(ans[3][2], d[a2.x][a2.y][k]);
ans[3][1] = min(ans[3][1], d[a1.x][a1.y][k]);
}
ll ans1 = (ll)ans[2][1] + ans[3][1], ans2 = (ll)ans[1][2] + ans[3][2], ans3 = (ll)ans[1][3] + ans[2][3];
//printf("look %d %d %d\n", ans1, ans2, ans3);
if(ans1 > 1e9 && ans2 > 1e9 && ans3 > 1e9) cout << "NO";
else if(ans1 <= ans2 && ans1 <= ans3) cout << 'X' << endl << ans1;
else if(ans2 <= ans1 && ans2 <= ans3) cout << 'Y' << endl << ans2;
else if(ans3 <= ans1 && ans3 <= ans2) cout << 'Z' << endl << ans3;
}

BZOJ2143: 飞飞侠的更多相关文章

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

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

  2. 2018.11.05 bzoj2143: 飞飞侠(最短路)

    传送门 最短路好题. 考虑对每个二维坐标建立一个高度属性. 这样每次如果在点(i,j,0)(i,j,0)(i,j,0)只能选择花费bi,jb_{i,j}bi,j​跳向(i,j,ai,j)(i,j,a_ ...

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

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

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

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

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

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

  6. 【BZOJ 2143】 飞飞侠

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

  7. BZOJ 2143 飞飞侠(分层最短路)

    飞飞国是一个N×M的矩形方阵,每个格子代表一个街区.然而飞飞国是没有交通工具的.飞飞侠完全靠地面的弹射装置来移动.每个街区都装有弹射装置.使用弹射装置是需要支付一定费用的.而且每个弹射装置都有自己的弹 ...

  8. luogu4473 BZOJ2143 2011[国家集训队]飞飞侠

    题目戳这里 有问题可以在博客@ 应该还会有人来看吧,嘻嘻 正题: 题目大意: 题目很清楚,就是一个点有一定的范围,会有一定的花费 求三个点中的任意两个点到另一个点的最小花费 (麻麻教育我千万读好题目( ...

  9. bzoj 2143: 飞飞侠

    #include<cstdio> #include<iostream> #include<queue> #define inf 1000000000 #define ...

随机推荐

  1. Optimal Marks SPOJ 839

    这题远超其他题非常靠近最小割的实际意义: 割边<=>付出代价<=>决定让两个点的值不相同,边权增加 最小割<=>点的值与s一个阵营的与s相同,与t一个阵营的与t相同 ...

  2. 彻底解决MacOS上应用程序快捷键冲突的问题,自定义快捷键设置

    1看图操作 上面选择好你要修改的应用程序的快捷键 ,我以Chrome为例子 最后点击下ADD 然后回到Chrome的菜单,发现刷新页的快捷键变成了F5 注意,快捷键的名字要和你Chrome菜单上的名字 ...

  3. 开源litemall学习

    1参数拼装 https://blog.yeskery.com/articles/345298282 WxWebMvcConfiguration HandlerMethodArgumentResolve ...

  4. 417 事件、监听、jQuery、轮播手动

    am:通用事件 a链接事件阻止默认行为 return false HTML元素大都包含了自己的默认行为,例如:超链接.提交按钮等.我们可以通过在绑定事件中加上return false来阻止它的默认行为 ...

  5. 2019年一次java知识点总结

    java基础 数据类型 集合与数据结构 关键字(static,rty ...) IO和网络 多线程(并发与锁,死锁) 异常 简单算法,复杂度 JVM 类加载 java内存模型 对象监听器字节码 垃圾回 ...

  6. 【转】Python3—UnicodeEncodeError 'ascii' codec can't encode characters in position 0-1

    转自:https://blog.csdn.net/AckClinkz/article/details/78538462 环境 >>> import sys >>> ...

  7. PHP Request请求封装

    /** * Request请求封装 * Class Request * @package tool */ class Request { // curl 请求错误码 protected static ...

  8. C++入门篇六

    struct和class的访问权限:结构体,类 struct和class 是相同的,唯一的而不同,就是默认权限,struct是public,class默认是private class Animal { ...

  9. TopN案例

    准备三份数据 t1 2067 t2 2055 t3 2055 t4 1200 t5 2367 t6 255 t7 2555 t8 12100 t9 20647 t10 245 t11 205 t12 ...

  10. Day04.a(对象类型的转换,多态)

    对象类型的转换 Dog dog = new Dog(); 通常情况下,对象(new Dog())类型和引用(dog)类型是相同的,当引用类型和对象类型不一致时,就需要类型转换. 向上转型:将较具体的类 ...