ZROI2018普转提day1t4

传送门

分析

就是飞飞侠这道题......

我们可以将这张图建成好几层,每一层可以向下一层的上下左右无代价移动,而对于每个点如果付b[i][j]的代价就可以走到比它高a[i][j]的层上。我们用这种方式优化了建边,然后跑个最短路就行了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define ri register int
const long long inf = 1e12+7;
const int dx[5] = {1,-1,0,0,0};
const int dy[5] = {0,0,1,-1,0};
inline int ra(){
      int x=0;char s=getchar();while(!isdigit(s))s=getchar();
      while(isdigit(s)){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}return x;
}
inline long long ra2(){
      long long x=0;char s=getchar();while(!isdigit(s))s=getchar();
      while(isdigit(s)){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}return x;
}
struct node {long long wh;int x,y,z;};
bool operator < (node p,node q){return p.wh>q.wh;}
int n,m,a[210][210],vis[210][210][420],x[4],y[4];
priority_queue<node>q;
long long b[210][210],d[210][210][420],w[4];
inline void dij(int s,int t1,int t2){
      node A,B;
      for(ri i=1;i<=n;++i)
        for(ri j=1;j<=m;++j)
          for(ri k=0;k<=n+m;++k)d[i][j][k]=inf,vis[i][j][k]=0;
      while(!q.empty())q.pop();
      d[x[s]][y[s]][0]=0;
      A.wh=0,A.x=x[s],A.y=y[s],A.z=0;
      q.push(A);
      while(!q.empty()){
          if(vis[x[0]][y[0]][0]&&vis[x[1]][y[1]][0]&&vis[x[2]][y[2]][0])
          break;
          A=q.top();q.pop();
          if(vis[A.x][A.y][A.z])continue;
          vis[A.x][A.y][A.z]=1;
          if(A.z>0){
            for(ri i=0;i<5;++i){
                if(dx[i]+A.x<1||dx[i]+A.x>n)continue;
                if(dy[i]+A.y<1||dy[i]+A.y>m)continue;
                if(d[A.x+dx[i]][A.y+dy[i]][A.z-1]>A.wh){
                  d[A.x+dx[i]][A.y+dy[i]][A.z-1]=A.wh;
                  B.x=A.x+dx[i],B.y=A.y+dy[i],B.z=A.z-1,B.wh=A.wh;
                  q.push(B);
                }
            }
          }else {
            if(d[A.x][A.y][a[A.x][A.y]]>A.wh+b[A.x][A.y]){
                d[A.x][A.y][a[A.x][A.y]]=A.wh+b[A.x][A.y];
                B.x=A.x,B.y=A.y,B.z=a[A.x][A.y],B.wh=A.wh+b[A.x][A.y];
                q.push(B);
            }
          }
      }
      w[t1]+=d[x[t1]][y[t1]][0],w[t2]+=d[x[t2]][y[t2]][0];
      return;
}
int main(){
      int out;
      n=ra(),m=ra();
      for(ri i=1;i<=n;++i)
        for(ri j=1;j<=m;++j)
          a[i][j]=ra(),a[i][j]=min(a[i][j],n+m);
      for(ri i=1;i<=n;++i)
        for(ri j=1;j<=m;++j)
          b[i][j]=ra2();
      for(ri i=0;i<3;++i)x[i]=ra(),y[i]=ra();
      long long minn=inf;
      dij(0,1,2),dij(1,0,2),dij(2,0,1);
      if(w[0]<minn)minn=w[0],out=0;
      if(w[1]<minn)minn=w[1],out=1;
      if(w[2]<minn)minn=w[2],out=2;
      if(minn>=inf)puts("NO");
        else cout<<char(out+'X')<<endl<<minn<<endl;
      return 0;
}
posted @ 2018-09-25 15:47  水题收割者  阅读(233)  评论(0编辑  收藏  举报