zoukankan      html  css  js  c++  java
  • 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
    %lld",pos,ans);
        return 0;
    }
  • 相关阅读:
    证券交易买进卖出手续费公式
    iOS学习之 plist文件的读写
    蓝桥杯——基础练习之字母图形
    SNMP协议具体解释
    Android开发框架SmartAndroid2.0 强劲框架
    隐藏快捷方式扩展名(.lnk)
    Filter及FilterChain的使用具体解释
    uva 1393
    深入浅出Windows BATCH
    科大讯飞2014公布会看点二:智能语音装进车载车机!
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8420891.html
Copyright © 2011-2022 走看看