• BZOJ 2143 飞飞侠(分层最短路)


    飞飞国是一个N×M的矩形方阵,每个格子代表一个街区。然而飞飞国是没有交通工具的。飞飞侠完全靠地面的弹射装置来移动。每个街区都装有弹射装置。使用弹射装置是需要支付一定费用的。而且每个弹射装置都有自己的弹射能力。我们设第i行第j列的弹射装置有Aij的费用和Bij的弹射能力。并规定有相邻边的格子间距离是1。那么,任何飞飞侠都只需要在(i,j)支付Aij的费用就可以任意选择弹到距离不超过Bij的位置了。现在的问题很简单。有三个飞飞侠,分别叫做X,Y,Z。现在它们决定聚在一起玩,于是想往其中一人的位置集合。告诉你3个飞飞侠的坐标,求往哪里集合大家需要花的费用总和最低。

    考虑直接建图,点n*m,边n*n*m*m,不可行。

    考虑将整个矩形再加一维,表示高度,那么对于最下面一层的点,连向的边是他对应Bij的高度,然后其他的点就向相邻位置的下一层连边。

    这样点n*m*(maxBij),边n*m*(maxBij)*5.

    实际上maxBij只要超过(n+m)的时候就可以到达图上任意一点,所以实际上maxBij只会<=(n+m).

    然后对于三个飞飞侠跑三遍最短路即可。

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <bitset>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi acos(-1.0)
    # define eps 1e-8
    # define MOD 1000000007
    # define INF 1000000000
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FDR(i,a,n) for(int i=a; i>=n; --i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    inline int Scan() {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    inline void Out(int a) {
        if(a<0) {putchar('-'); a=-a;}
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=155;
    //Code begin....
    
    int A[N][N], B[N][N], ps[5][2]={0,0,-1,0,1,0,0,-1,0,1};
    int n, m, node[3];
    LL dist[N*N*N*3], d[3][3];
    bool vis[N*N*N*3];
    struct qnode{
        int v;
        LL c;
        qnode(int _v=0, LL _c=0):v(_v),c(_c){}
        bool operator<(const qnode &r)const{return c>r.c;}
    };
    priority_queue<qnode>que;
    const LL P=1LL<<60;
    
    int get_id(int x, int y, int z){return n*m*(z-1)+(y-1)*n+(x-1);}
    void Dijkstra(int nn, int start){
        int u, x, y, z, px, py, pz, id;
        mem(vis,false);
        FOR(i,0,nn) dist[i]=P;
        dist[node[start]]=0;
        while (!que.empty()) que.pop();
        que.push(qnode(node[start],0));
        qnode tmp;
        while (!que.empty()) {
            if (dist[node[0]]!=P && dist[node[1]]!=P && dist[node[2]]!=P) break;
            tmp=que.top(); que.pop();
            u=tmp.v;
            if (vis[u]) continue;
            vis[u]=true;
            z=u/(n*m)+1; y=(u%(n*m))/n+1; x=u%(n*m)%n+1;
            if (z==1) {
                pz=min(n+m,1+B[x][y]); id=get_id(x,y,pz);
                if (!vis[id]&&dist[id]>dist[u]+A[x][y]) dist[id]=dist[u]+A[x][y], que.push(qnode(id,dist[id]));
            }
            else {
                FOR(i,0,4) {
                    px=x+ps[i][0]; py=y+ps[i][1];
                    if (px<=0||px>n||py<=0||py>m) continue;
                    id=get_id(px,py,z-1);
                    if (!vis[id]&&dist[id]>dist[u]) dist[id]=dist[u], que.push(qnode(id,dist[id]));
                }
            }
        }
        FOR(i,0,2) d[start][i]=dist[node[i]];
    }
    int main ()
    {
        int x, y;
        n=Scan(); m=Scan();
        FOR(i,1,n) FOR(j,1,m) B[i][j]=Scan();
        FOR(i,1,n) FOR(j,1,m) A[i][j]=Scan();
        FOR(i,0,2) x=Scan(), y=Scan(), node[i]=get_id(x,y,1);
        FOR(i,0,2) Dijkstra(n*m*(n+m+1),i);
        LL ans=P;
        int p;
        FOR(i,0,2) if (ans>d[0][i]+d[1][i]+d[2][i]) ans=d[0][i]+d[1][i]+d[2][i], p=i;
        if (ans==P) puts("NO");
        else {
            if (p==0) puts("X");
            else if (p==1) puts("Y");
            else puts("Z");
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    子程序的设计
    多重循环程序设计
    汇编语言的分支程序设计与循环程序设计
    代码调试之串口调试2
    毕昇杯模块之光照强度传感器
    毕昇杯之温湿度采集模块
    【CSS】盒子模型 之 IE 与W3C的盒子模型对比
    【css】盒子模型 之 概述
    【css】盒子模型 之 弹性盒模型
    【网络】dns_probe_finished_nxdomain 错误
  • 原文地址:https://www.cnblogs.com/lishiyao/p/7299961.html
Copyright © 2020-2023  润新知