bzoj千题计划225:bzoj2143: 飞飞侠
http://www.lydsy.com/JudgeOnline/problem.php?id=2143
分层图最短路
把能够弹跳的曼哈顿距离看做能量
dp[i][j][k]表示在(i,j)位置,还有能量k的最少花费
弹跳的曼哈顿距离增加1,能量减1
当能量减为0时,花费费用充满能量
#include<queue> #include<cstdio> #include<iostream> #define N 151 typedef long long LL; const LL inf=1e17; using namespace std; int n,m; int energy[N][N],cost[N][N]; int X[4],Y[4]; LL dp[N][N][N<<1]; bool vis[N][N][N<<1]; int dx[5]={0,-1,0,1,0}; int dy[5]={0,0,1,0,-1}; struct node { int x,y,k; LL val; node(int x_=0,int y_=0,int k_=0,int val_=0) :x(x_),y(y_),k(k_),val(val_) {} bool operator < (node p) const { return val>p.val; } }now; priority_queue<node>q; void read(int &x) { x=0; int f=1; char c=getchar(); while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } x*=f; } void dijkstra(int e) { for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) for(int k=0;k<=n+m-2;++k) { dp[i][j][k]=inf; vis[i][j][k]=false; } while(!q.empty()) q.pop(); vis[X[e]][Y[e]][0]=true; dp[X[e]][Y[e]][energy[X[e]][Y[e]]]=cost[X[e]][Y[e]]; now.x=X[e]; now.y=Y[e]; now.k=energy[now.x][now.y]; now.val=cost[now.x][now.y]; q.push(now); int sx,sy,nx,ny,k; while(!q.empty() && (!vis[X[1]][Y[1]][0] || !vis[X[2]][Y[2]][0] || !vis[X[3]][Y[3]][0])) { now=q.top(); q.pop(); sx=now.x; sy=now.y; k=now.k; if(vis[sx][sy][k]) continue; vis[sx][sy][k]=true; if(now.k) { for(int i=0;i<5;++i) { nx=now.x+dx[i]; ny=now.y+dy[i]; if(nx<=0 || nx>n || ny<=0 || ny>m) continue; if(dp[sx][sy][k]<dp[nx][ny][k-1]) { dp[nx][ny][k-1]=dp[sx][sy][k]; q.push(node(nx,ny,k-1,dp[nx][ny][k-1])); } } } else { if(dp[sx][sy][0]+cost[sx][sy]<dp[sx][sy][energy[sx][sy]]) { dp[sx][sy][energy[sx][sy]]=dp[sx][sy][0]+cost[sx][sy]; q.push(node(sx,sy,energy[sx][sy],dp[sx][sy][energy[sx][sy]])); } } } } int main() { int x; read(n); read(m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { read(x); energy[i][j]=min(x,max(i-1,n-i)+max(j-1,m-j)); } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) read(cost[i][j]); for(int i=1;i<=3;++i) read(X[i]),read(Y[i]); LL ans=inf; char pos; dijkstra(1); LL a1=dp[X[2]][Y[2]][0],a2=dp[X[3]][Y[3]][0]; dijkstra(2); LL b1=dp[X[1]][Y[1]][0],b2=dp[X[3]][Y[3]][0]; dijkstra(3); LL c1=dp[X[1]][Y[1]][0],c2=dp[X[2]][Y[2]][0]; if(b1+c1<ans) ans=b1+c1,pos='X'; if(a1+c2<ans) ans=a1+c2,pos='Y'; if(a2+b2<ans) ans=a2+b2,pos='Z'; if(ans>=inf) printf("NO"); else printf("%c\n%lld",pos,ans); return 0; }