Time Limit: 50 Sec Memory Limit: 259 MB

Description

飞飞国是一个传说中的国度,国家的居民叫做飞飞侠。飞飞国是一个N×M的矩形方阵,每个格子代表一个街区。然而飞飞国是没有交通工具的。飞飞侠完全靠地面的弹射装置来移动。每个街区都装有弹射装置。使用弹射装置是需要支付一定费用的。而且每个弹射装置都有自己的弹射能力。我们设第i行第j列的弹射装置有Aij的费用和Bij的弹

射能力。并规定有相邻边的格子间距离是\(1\)。那么,任何飞飞侠都只需要在(i,j)支付Aij的费用就可以任意选择弹

到距离不超过Bij的位置了。如下图

(从红色街区交费以后可以跳到周围的任意蓝色街区。)现在的问题很简单。有三个飞飞侠,分别叫做X,Y,Z。

现在它们决定聚在一起玩,于是想往其中一人的位置集合。告诉你3个飞飞侠的坐标,求往哪里集合大家需要花的

费用总和最低。

Input

输入的第一行包含两个整数\(N\)和\(M\),分别表示行数和列数。

接下来是2个N×M的自然数矩阵,为\(B_{i,j}\)和\(A_{i,j}\)

最后一行六个数,分别代表X,Y,Z所在地的行号和列号。

\(1\leq N,M\leq 150\);\(0\leq B_{i,j}\leq 10^9\);\(0\leq A_{i,j}\leq1000\)

Output

第一行输出一个字符X、Y或者Z。表示最优集合地点。

第二行输出一个整数,表示最小费用。如果无法集合,只输出一行NO

Sample Input

4 4
0 0 0 0
1 2 2 0
0 2 2 1
0 0 0 0
5 5 5 5
5 5 5 5
5 5 5 5
5 5 5 5
2 1 3 4 2 2

Sample Output

Z
15

Solution

嗯这道题的算法还是很有意思的,有时间还要再好好品味一下,真的是很新奇。

一眼最短路啊,但是如果我们直接跑Dijkstra的话(什么,这个世道你还敢用SPFA,更何况这还是网格图),转移数量太多了,肯定会T掉。

所以我们考虑一下转化,在一个点投射,相当于给了他一个\(B[i][j]\)的能量,然后每走一个消耗一个点数的能量。

那么我们设\(dist[i][j][k]\)表示走到\((i,j)\)这个点,还剩\(k\)点的能量的情况。那么转移就是这样的:

\[\begin{align*}
&dp[i][j][k]\rightarrow dp[x][y][k-1]\ \ |\ \ k>0,\text{$(x,y)$是与$(i,j)$香菱的点}\\
&dp[i][j][0]+a[i][j]\rightarrow dp[i][j][b[i][j]]\\
\end{align*}
\]

这样然后再加上Dijsktra的堆的复杂度就是\(O(n^3\log (n^3))\)的。比较卡常,在学校OJ上过不去,BZOJ上好像能过。

我们考虑优化。后面的学长们讨论了各种各样的优化,比如什么线段树优化建边,线段树进行转移,并查集优化最短路什么的。

但是这些我都不太会,所以只能自己YY出了一个实测效果很好的优化。显然Dijkstra里面每一次进行操作的点的\(dist\)值是单调不减的,所以如果遇到这样的情况我们可以直接跳过,不去转移:同一个点,如果已经操作过比现在这个状态能量要多的点,那么显然现在这个状态没有那个优,就可以不去转移了。我们只需要每次都转移那些能量大于曾经转移过的同一个点的能量值最大值的状态。这样的话,我们可以优化掉很多没有用的状态,实测效果不错,在BZOJ上排到了第二页,不过还是比不上那些神一样的并查集优化最短路。

但是遗憾的是,好像这样的复杂度还是没有变的,大家也许可以叉一叉。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define REP(i,a,n) for(register int i=(a);i<=(n);++i)
#define PER(i,a,n) for(register int i=(a);i>=(n);--i)
#define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
namespace io{
const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
inline void putc(char x){*oS++=x;if(oS==oT)flush();}
template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;}
template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);}
inline void print(const char *s){while(*s!='\0')putc(*s++);}
inline void scan(char *s){for(c=gc();c<=' ';c=gc());for(;c>' ';c=gc())*(s++)=c;*s='\0';}
struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}//orz laofudasuan
using io::read;using io::putc;using io::write;using io::print;
typedef long long ll;typedef unsigned long long ull;
template<typename A,typename B>inline bool SMAX(A&x,const B&y){return x<y?x=y,1:0;}
template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;} const int N=150+3,INF=0x3f3f3f3f,fx[]={0,0,1,0,-1},fy[]={0,1,0,-1,0};
int n,m,b[N][N],a[N][N],dist[N][N][N<<1],vis[N][N],flag1,flag2,X1,Y1,X2,Y2,X3,Y3,ans=INF,get[4][4];char ans2;//错误笔记:get[4][4]开成了get[3][3] struct Node{int x,y,en,dist;inline bool operator<(const Node&a)const{return dist>a.dist;}};priority_queue<Node>q; inline void Dijkstra(Node S,Node T1,Node T2,int &flag1,int &flag2){
memset(dist,0x3f,sizeof(dist));memset(vis,-1,sizeof(vis));while(!q.empty())q.pop();
dist[S.x][S.y][b[S.x][S.y]]=a[S.x][S.y];q.push(Node{S.x,S.y,b[S.x][S.y],a[S.x][S.y]});flag1=flag2=0;
while(!q.empty()){
Node p=q.top();q.pop();if(vis[p.x][p.y]>=p.en)continue;int flag=(vis[p.x][p.y]==-1);SMAX(vis[p.x][p.y],p.en);
if(p.x==T1.x&&p.y==T1.y&&!flag1)flag1=p.dist;if(p.x==T2.x&&p.y==T2.y&&!flag2)flag2=p.dist;if(flag1&&flag2)return;
for(register int i=0;i<=4;++i){
Node f=Node{p.x+fx[i],p.y+fy[i],p.en-1,p.dist};if(f.x<1||f.x>n||f.y<1||f.y>m)continue;
if(vis[f.x][f.y]<=f.en&&dist[f.x][f.y][f.en]>p.dist){
dist[f.x][f.y][f.en]=dist[p.x][p.y][p.en];
q.push(f);
}
}
if(flag){Node f=Node{p.x,p.y,b[p.x][p.y],p.dist+a[p.x][p.y]};
if(vis[f.x][f.y]<=f.en&&dist[f.x][f.y][f.en]>p.dist+a[p.x][p.y]){
dist[f.x][f.y][f.en]=p.dist+a[p.x][p.y];
q.push(f);
}}
}if(!flag1)flag1=INF;if(!flag2)flag2=INF;
} int main(){
#ifndef ONLINE_JUDGE
freopen("zhber.in","r",stdin);freopen("zhber.out","w",stdout);
#endif
read(n),read(m);
for(register int i=1;i<=n;++i)for(register int j=1;j<=m;++j)read(b[i][j]),SMIN(b[i][j],max(max(i-1+j-1,n-i+j-1),max(i-1+m-j,n-i+m-j)));
for(register int i=1;i<=n;++i)for(register int j=1;j<=m;++j)read(a[i][j]);
read(X1),read(Y1),read(X2),read(Y2),read(X3),read(Y3);
Dijkstra(Node{X1,Y1},Node{X2,Y2},Node{X3,Y3},get[1][2],get[1][3]);
Dijkstra(Node{X2,Y2},Node{X1,Y1},Node{X3,Y3},get[2][1],get[2][3]);
Dijkstra(Node{X3,Y3},Node{X1,Y1},Node{X2,Y2},get[3][1],get[3][2]);
if(SMIN(ans,get[2][1]+get[3][1]))ans2='X';
if(SMIN(ans,get[1][2]+get[3][2]))ans2='Y';
if(SMIN(ans,get[1][3]+get[2][3]))ans2='Z';
if(ans2<'X')print("NO\n");else putc(ans2),putc('\n'),write(ans),putc('\n');
}

BZOJ2143 飞飞侠 & [校内NOIP2018模拟20181026] 最强大脑的更多相关文章

  1. BZOJ2143: 飞飞侠

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

  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. BZOJ3508 开灯 & [校内NOIP2018模拟20181027] 密码锁

    Time Limit: 10 Sec Memory Limit: 128 MB Description xx作为信息学界的大神,拥有众多的粉丝.为了感谢众粉丝的爱戴,xx决定举办一场晚会.为了气派,x ...

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

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

  7. 【BZOJ 2143】 飞飞侠

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

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

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

  9. [NOIP2018模拟赛10.16]手残报告

    [NOIP2018模拟赛10.16]手残报告 闲扯 炉石乱斗模式美滋滋啊,又颓到好晚... 上来T2先敲了树剖,看T1发现是个思博DP,然后没过大样例,写个暴力发现还是没过大样例!?才发现理解错题意了 ...

随机推荐

  1. 项目部署到tomcat,浏览器能够访问,手机不能访问。

    问题:有这样一个问题,把项目部署到tomcat上,浏览器能够访问,但是手机不能访问. 解决:在 tomcat中找到conf文件夹,然后找到web.xml

  2. 禁止input输入框输入指定内容

    链接: http://blog.csdn.net/xiaoya_syt/article/details/52746598

  3. kibana使用日志时间进行排序

    kibana默认的是按照客户端的采集时间(@timestamp)进行排序,这往往不是我们所需要的,我们需要的是对日志实际时间进行排序,要解决这个问题,有很多种方法,可以在elasticsearch建立 ...

  4. 洛谷P1879 [USACO06NOV]玉米田Corn Fields(状压dp)

    洛谷P1879 [USACO06NOV]玉米田Corn Fields \(f[i][j]\) 表示前 \(i\) 行且第 \(i\) 行状态为 \(j\) 的方案总数.\(j\) 的大小为 \(0 \ ...

  5. Log4j Threshold、Append

    报错ERROR日志单独存放 Threshold属性可以指定日志level Log4j根据日志信息的重要程度,分OFF.FATAL.ERROR.WARN.INFO.DEBUG.ALL 比如我们指定某个a ...

  6. Gym 100917M Matrix, The

    题目链接: http://codeforces.com/gym/100917/problem/M --------------------------------------------------- ...

  7. win10 文件管理器频繁卡死

    参考: https://www.xitmi.com/1589.html

  8. JS基础(下)

    事件DOM Event 更多事件请查询h3c  htmldom参考手册  event onclick() :当点击时 onfocus() :获得焦点时 :当点击某个区域时触发,如点击输入框 onblu ...

  9. 应用安全-工具使用-Burpsuite

    A cheat sheet for PortSwigger Burp Suite application security testing framework. Send to Repeater Ct ...

  10. Java中的类修饰符

    资料主要来源于网络(http://60.28.60.3/zy/java-new/zhishidian/chap3/3.htm) 之前每次写小测试程序的时候,总是把一个类放在一个Java文件中,按理说这 ...