Description
飞飞国是一个传说中的国度,国家的居民叫做飞飞侠。飞飞国是一个N×M的矩形方阵,每个格子代表一个街区。
然而飞飞国是没有交通工具的。飞飞侠完全靠地面的弹射装置来移动。
每个街区都装有弹射装置。使用弹射装置是需要支付一定费用的。而且每个弹射装置都有自己的弹射能力。
我们设第i行第j列的弹射装置有Aij的费用和Bij的弹射能力。并规定有相邻边的格子间距离是1。那么,任何飞飞侠都只需要在(i,j)支付Aij的费用就可以任意选择弹到距离不超过Bij的位置了。如下图
(从红色街区交费以后可以跳到周围的任意蓝色街区。)
现在的问题很简单。有三个飞飞侠,分别叫做X,Y,Z。现在它们决定聚在一起玩,于是想往其中一人的位置集合。告诉你3个飞飞侠的坐标,求往哪里集合大家需要花的费用总和最低。
Data Constraint
20% N, M ≤ 10; Bij ≤ 20
40% N, M ≤ 100; Bij ≤ 20
100% 1 ≤ N, M ≤ 150; 0 ≤ Bij ≤ 10^9; 0 ≤ Aij ≤ 1000
Solution
sb题,考试的时候大概是懵了连最短路都不会了
暴力连边会t因此直接带着坐标跑,spfa大概率会被卡因此slfllf随便上
感觉题解脑洞太大了,说白了就是做成分层图跑会少很多无用的边,但是我死活改不出那种做法就算了吧
Code
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
const int INF=0x3f3f3f3f;
const int L=151;
struct pos{int x,y;};
std:: deque<pos> que;
int a[L][L],b[L][L];
int dis[3][L][L];
bool vis[L][L];
int n,m;
char prt;
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void spfa(pos st,pos ed1,pos ed2,int d[L][L]) {
while (!que.empty()) que.pop_back();
rep(i,0,n) rep(j,0,m) d[i][j]=INF;
fill(vis,0);
d[st.x][st.y]=0;
vis[st.x][st.y]=1;
que.push_back(st);
while (!que.empty()) {
pos now=que.front(); que.pop_front();
int A=a[now.x][now.y];
int B=b[now.x][now.y];
rep(i,max(now.x-B,1),min(now.x+B,n)) {
int tmp=std:: abs(now.x-i);
rep(j,max(now.y-B+tmp,1),min(now.y+B-tmp,m)) {
if (d[now.x][now.y]+A<d[i][j]) {
d[i][j]=d[now.x][now.y]+A;
if (!vis[i][j]) {
vis[i][j]=1;
if (que.empty()) que.push_back((pos){i,j});
else {
pos fr=que.front();
if (dis[fr.x][fr.y]>dis[i][j]) que.push_front((pos){i,j});
else que.push_back((pos){i,j});
}
}
}
}
}
vis[now.x][now.y]=0;
}
}
int main(void) {
n=read();
m=read();
rep(i,1,n) rep(j,1,m) b[i][j]=read();
rep(i,1,n) rep(j,1,m) a[i][j]=read();
int x1=read(); int y1=read(); pos pos1=(pos){x1,y1};
int x2=read(); int y2=read(); pos pos2=(pos){x2,y2};
int x3=read(); int y3=read(); pos pos3=(pos){x3,y3};
spfa(pos1,pos2,pos3,dis[0]);
spfa(pos2,pos1,pos3,dis[1]);
spfa(pos3,pos1,pos2,dis[2]);
int d,ans=INF;
if ((d=dis[1][x1][y1]+dis[2][x1][y1])<ans) {
ans=d;
prt='X';
}
if ((d=dis[0][x2][y2]+dis[2][x2][y2])<ans) {
ans=d;
prt='Y';
}
if ((d=dis[0][x3][y3]+dis[1][x3][y3])<ans) {
ans=d;
prt='Z';
}
if (ans==INF) puts("NO");
else printf("%c\n%d\n",prt,ans);
return 0;
}