zoukankan      html  css  js  c++  java
  • 【BZOJ2143】飞飞侠

    2143: 飞飞侠

    Time Limit: 50 Sec  Memory Limit: 259 MB
    Submit: 794  Solved: 275
    [Submit][Status][Discuss]

    Description

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

    Input

    输入的第一行包含两个整数N和M,分别表示行数和列数。接下来是2个N×M的自然数矩阵,为Aij和Bij 最后一行六个数,分别代表X,Y,Z所在地的行号和列号。

    Output

    第一行输出一个字符X、Y或者Z。表示最优集合地点。第二行输出一个整数,表示最小费用。如果无法集合,只输出一行NO

    Sample Input

    4 4
    0 0 0 0
    1 2 2 0
    0 2 2 1
    0 0 0 0
    5 5 5 5
    5 5 5 5
    5 5 5 5
    5 5 5 5
    2 1 3 4 2 2

    Sample Output

    Z
    15
    【范围】
    100% 1 < = N, M < = 150; 0 < = Aij < = 10^9; 0 < = Bij < = 1000
     
    题解:
    垃圾题目毁我人生颓我青春
    在湖南我有两天都在写这个垃圾题
    首先我们发现某个弹射装置就是多条边,这样我们可以转化为求平面图上最短路
    但是会T,因为边数过多,所以我们要用点来疏松边
    具体怎么做呢?我们再加一维,表示当前高度
    dis[i][j][k]表示现在在ij,高度为k的最短路
    这样转化之后就可以不用边了
    这样复杂度很玄学 但是能过
    就这样 我来贴一波代码
    #include<cstdio> 
    #include<cstdlib> 
    #include<iostream> 
    #include<cstring> 
    #include<algorithm> 
    #include<queue> 
    #include<iomanip> 
    #include<stack> 
    #include<map> 
    #include<set> 
    #include<cmath> 
    #define debug(x) cerr<<#x<<"="<<x<<endl 
    #define INF 0x7f7f7f7f 
    #define llINF 0x7ffffffffffll 
    using namespace std; 
    typedef pair<int,int> pii; 
    typedef long long ll; 
    inline int init() 
    { 
        int now=0,ju=1;char c;bool flag=false; 
        while(1) 
        { 
            c=getchar(); 
            if(ju=='-')ju=-1; 
            else if(c>='0'&&c<='9') 
            { 
                now=now*10+c-'0'; 
                flag=true; 
            } 
            else if(flag)return now*ju; 
        } 
    } 
    ll dis[151][151][1005]; 
    int n,m; 
    ll ans=llINF;  
    bool vis[151][151][1005]; 
    int A[151][151]; 
    int B[151][151];  
    struct node 
    { 
        int x,y,z; 
        ll dis; 
    }; 
    bool operator < (node a,node b) 
    { 
        if(a.dis!=b.dis) 
        { 
            return a.dis>b.dis; 
        } 
    } 
    int topt;  
    char where; 
    #ifdef unix 
        #define LLD "%lld" 
    #else 
        #define LLD "%I64d" 
    #endif  
    int xx,xy,yx,yy,zx,zy;
    priority_queue<node> q; 
    int dx[5]={1,-1,0,0,0}; 
    int dy[5]={0,0,1,-1,0};  
    void dijkstra(int x,int y)
    {
        node now;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int k=0;k<=topt;k++)
                {
                    dis[i][j][k]=llINF;
                    vis[i][j][k]=false;
                }
            }
        }
        dis[x][y][0]=0;
        now.x=x;now.y=y;now.z=0;now.dis=0;
        q.push(now);
        while(!q.empty())
        {
            now=q.top();q.pop();
            if(vis[now.x][now.y][now.z])continue;
            if(vis[xx][xy][0]+vis[yx][yy][0]+vis[zx][zy][0]==3)break;
            vis[now.x][now.y][now.z]=1;
            if(now.z>0)
            {
                for(int i=0;i<5;i++)
                {
                    if(!vis[now.x+dx[i]][now.y+dy[i]][now.z-1]&&now.x+dx[i]>=1&&now.x+dx[i]<=n&&now.y+dy[i]>=1&&now.y+dy[i]<=m)
                    {
                        if(dis[now.x+dx[i]][now.y+dy[i]][now.z-1]>dis[now.x][now.y][now.z])
                        {
                            dis[now.x+dx[i]][now.y+dy[i]][now.z-1]=dis[now.x][now.y][now.z];
                            q.push((node){now.x+dx[i],now.y+dy[i],now.z-1,dis[now.x+dx[i]][now.y+dy[i]][now.z-1]});
                        }
                    }
                }
            }
            else
            {
                if(!vis[now.x][now.y][B[now.x][now.y]])
                {
                    if(dis[now.x][now.y][B[now.x][now.y]]>dis[now.x][now.y][0]+A[now.x][now.y])
                    {
                        dis[now.x][now.y][B[now.x][now.y]]=dis[now.x][now.y][0]+A[now.x][now.y];
                        q.push((node){now.x,now.y,B[now.x][now.y],dis[now.x][now.y][B[now.x][now.y]]});
                    }
                }
            }
              
        }
        while(!q.empty())q.pop();
    }
    ll xty,xtz,ytx,ytz,ztx,zty;
    int main()  
    { 
        n=init();m=init(); 
        for(int i=1;i<=n;i++) 
        { 
            for(int j=1;j<=m;j++) 
            { 
                B[i][j]=init();
                B[i][j]=min(B[i][j],n+m+1);
                topt=max(B[i][j],topt); 
            }  
        } 
        for(int i=1;i<=n;i++) 
        { 
            for(int j=1;j<=m;j++) 
            { 
                A[i][j]=init(); 
            } 
        }  
        xx=init();xy=init();yx=init();yy=init();zx=init();zy=init();
        dijkstra(xx,xy); 
        xty=dis[yx][yy][0]; 
        xtz=dis[zx][zy][0]; 
        dijkstra(yx,yy); 
        ytx=dis[xx][xy][0]; 
        ytz=dis[zx][zy][0]; 
        dijkstra(zx,zy); 
        ztx=dis[xx][xy][0]; 
        zty=dis[yx][yy][0]; 
        if(ytx+ztx<ans)
        {
            where='X';
            ans=ytx+ztx;
        }
        if(xty+zty<ans)
        {
            where='Y';
            ans=xty+zty;
        }
        if(xtz+ytz<ans)
        {
            where='Z';
            ans=xtz+ytz;
        }
        if(ans==llINF) 
        { 
            printf("NO
    "); 
        } 
        else printf("%c
    "LLD,where,ans); 
        return 0;  
    } 
    /* 
    srO xudyh davidlee1999WTK linkct1999 zlser Orz 
    */
    View Code
  • 相关阅读:
    3.12
    3.11
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
    安卓开发
  • 原文地址:https://www.cnblogs.com/redwind/p/6492491.html
Copyright © 2011-2022 走看看