zoukankan      html  css  js  c++  java
  • bzoj2143 飞飞侠

    飞飞侠

    Time Limit: 50 Sec Memory Limit: 259 MB

    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所在地的行号和列号。
    1<=N,M<=150;0<=Aij<=10^9;0<=Bij<=1000

    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



    这道题还是很不错的。。。。 分层分成300层贼秀。。。。 但是我可能把 maxn >> 1 当成乘2了。。。 网上前两个std都是wa的。。。我拍了一万年。。。。 傻逼的我最后终于gou过去了。。。
    ```c++

    include<bits/stdc++.h>

    using namespace std;
    const int maxn = 155;
    const long long INF = 2e16 + 5;
    struct lpl{
    int i, j, k; long long dis;
    bool operator < (const lpl &A)const{
    return dis > A.dis;
    }
    }node[maxn][maxn][maxn >> 1], lin, qwe;
    int n, m, maxh, sz, pn[5], pm[5], pa[] = {-1, 0, 1, 0, 0}, pb[] = {0, 1, 0, -1, 0};
    int A[maxn][maxn], B[maxn][maxn];
    long long ans, dis[maxn][maxn][maxn << 1], p[5][5];
    bool vis[maxn][maxn][maxn << 1];
    priority_queue q;

    inline int read()
    {
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
    }

    inline bool check(int i, int j){return (i >= 1 && i <= n && j >= 1 && j <= m);}

    inline void putit()
    {
    n = read(); m = read(); sz = n * m;
    for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j){
    A[i][j] = read(); A[i][j] = min(A[i][j], max(i - 1, n - i) + max(j - 1, m - j));
    maxh = max(maxh, A[i][j]);
    }
    for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
    B[i][j] = read();
    for(int i = 1; i <= 3; ++i) pn[i] = read(), pm[i] = read();
    }

    inline void dijkstra(int a, int b)
    {
    int ii, jj, kk; memset(vis, false, sizeof(vis));
    for(int i = 1; i <= n; ++i)
    for(int j = 1; j <= m; ++j)
    for(int k = 0; k <= 300; ++k)
    dis[i][j][k] = 2e16;
    ans = dis[1][1][1];
    node[a][b][0].i = a; node[a][b][0].j = b; node[a][b][0].k = 0;
    node[a][b][0].dis = 0; dis[a][b][0] = 0; q.push(node[a][b][0]);
    while(!q.empty()){
    lin = q.top(); q.pop(); ii = lin.i; jj = lin.j; kk = lin.k;
    if(vis[ii][jj][kk]) continue;
    if(vis[pn[1]][pm[1]][0] && vis[pn[2]][pm[2]][0] && vis[pn[3]][pm[3]][0]) break;
    vis[ii][jj][kk] = true;
    if(dis[ii][jj][A[ii][jj]] > lin.dis + B[ii][jj]){
    dis[ii][jj][A[ii][jj]] = lin.dis + B[ii][jj];
    qwe = lin; qwe.k = A[ii][jj]; qwe.dis = lin.dis + B[ii][jj];
    q.push(qwe);
    }
    if(!lin.k) continue; kk = lin.k - 1;
    for(int w = 0; w <= 4; ++w){
    if(!check(lin.i + pa[w], lin.j + pb[w])) continue;
    ii = lin.i + pa[w]; jj = lin.j + pb[w];
    if(dis[ii][jj][kk] > lin.dis){
    dis[ii][jj][kk] = lin.dis;
    qwe.i = ii; qwe.j = jj; qwe.k = kk; qwe.dis = lin.dis;
    q.push(qwe);
    }
    }
    }
    while(!q.empty()) q.pop();
    }

    int main()
    {
    putit();
    dijkstra(pn[1], pm[1]);
    p[1][2] = dis[pn[2]][pm[2]][0]; p[1][3] = dis[pn[3]][pm[3]][0];
    dijkstra(pn[2], pm[2]);
    p[2][1] = dis[pn[1]][pm[1]][0]; p[2][3] = dis[pn[3]][pm[3]][0];
    dijkstra(pn[3], pm[3]);
    p[3][1] = dis[pn[1]][pm[1]][0]; p[3][2] = dis[pn[2]][pm[2]][0];
    char t = 'Q';
    if(p[2][1] + p[3][1] < ans){
    ans = p[2][1] + p[3][1]; t = 'X';
    }
    if(p[1][2] + p[3][2] < ans){
    ans = p[1][2] + p[3][2]; t = 'Y';
    }
    if(p[1][3] + p[2][3] < ans){
    ans = p[1][3] + p[2][3]; t = 'Z';
    }
    if(t == 'Q'){printf("NO"); return 0;}
    cout << t << endl << ans;
    return 0;
    }

    心如花木,向阳而生。
  • 相关阅读:
    在Linux上使用C语言编程获取IPv4地址及子网掩码
    使用gdb进行写操作
    [中英对照]The Art Of Reporting Bugs | 报bug的艺术
    [中英对照]Introduction to Remote Direct Memory Access (RDMA) | RDMA概述
    Intel万兆网卡背靠背连接ping不通那点事儿
    [中英对照]The sysfs Filesystem | sysfs文件系统
    图说单播,组播,广播,选播和地域播
    Ubuntu双网卡不双待攻略
    反汇编容易反编译难
    PHP之路——微信公众号授权获取用户信息
  • 原文地址:https://www.cnblogs.com/LLppdd/p/9238085.html
Copyright © 2011-2022 走看看