• [题解] PowerOJ 1750 汽车加油行驶问题 (最短路)


    - 传送门 -

     https://www.oj.swust.edu.cn/problem/show/1750

    # 1750: 汽车加油行驶问题

    Time Limit: 1000 MS Memory Limit: 65536 KB
    Total Submit: 55 Accepted: 31 Page View: 824

    Description

    给定一个N*N 的方形网格,设其左上角为起点◎,坐标为(1,1),X 轴向右为正,Y 轴向下为正,每个方格边长为1,如图所示。一辆汽车从起点◎出发驶向右下角终点▲,其 坐标为(N,N)。在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在 行驶过程中应遵守如下规则: (1)汽车只能沿网格边行驶,装满油后能行驶K 条网格边。出发时汽车已装满油,在起 点与终点处不设油库。 (2)汽车经过一条网格边时,若其X 坐标或Y 坐标减小,则应付费用B,否则免付费用。 (3)汽车在行驶过程中遇油库则应加满油并付加油费用A。 (4)在需要时可在网格点处增设油库,并付增设油库费用C(不含加油费用A)。 (5)(1)~(4)中的各数N、K、A、B、C均为正整数,且满足约束:2<=N<=100,2<=K<=10。 设计一个算法,求出汽车从起点出发到达终点的一条所付费用最少的行驶路线。 对于给定的交通网格,计算汽车从起点出发到达终点的一条所付费用最少的行驶路线。

    Input

    由文件input.txt提供输入数据。文件的第一行是N,K,A,B,C的值。第二行起是一 个N*N 的0-1 方阵,每行N 个值,至N+1 行结束。方阵的第i 行第j 列处的值为1 表示在 网格交叉点(i,j)处设置了一个油库,为0 时表示未设油库。各行相邻两个数以空格分隔。

    Output

    程序运行结束时,将最小费用输出到文件output.txt中。

    9 3 2 3 6
    0 0 0 0 1 0 0 0 0
    0 0 0 1 0 1 1 0 0
    1 0 1 0 0 0 0 1 0
    0 0 0 0 0 1 0 0 1
    1 0 0 1 0 0 1 0 0
    0 1 0 0 0 0 0 1 0
    0 0 0 0 1 0 0 0 1
    1 0 0 1 0 0 0 1 0
    0 1 0 0 0 0 0 0 0

    12

    Source

    线性规划与网络流24题
     

    - 思路 -

     分层建模.
     以剩余油量((0...k))来分层.
     每一层包含所有节点.
     对于某层节点 (x) 来说:
     若该层油量不满:
      有加油站时: 连一条权值为 (a) 的边指向满油量的那一层的 (x) 点.
      无加油站时: 连一条权值为 (a+c) 的边指向满油量的那一层的 (x) 点.
     若该层油量满:
      向四个方向连边.
     若该层油量不满:
      有加油站时: 没有操作.(此时必须加油)
      无加油站时: 向四个方向连边.
     然后求最短路.
     起点为(<1,1,k>), 终点为(<n,n,x>, 0leq xleq k).
     细节见代码.
     

    - 代码 -

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    const int N = 2e5 + 50;
    const int M = 1e6;
    const int inf = 0x3f3f3f3f;
     
    int NXT[M], TO[M], V[M];
    int DIS[N], VIS[N], HD[N];
    int MAP[205][205];
    int C[205][205][15];
    int ss, tt, sz, k, n, m, a, b, c, tot;
    queue<int> q;
     
    int mk(int x, int y, int z) {
        return z * n * n + (x - 1) * n + y;
    }
     
    void add(int x, int y, int z) {
        TO[sz] = y; V[sz] = z;
        NXT[sz] = HD[x]; HD[x] = sz++;
    }
     
    int spfa() {
        memset(DIS, 0x3f, sizeof (DIS));
        DIS[ss] = 0;
        q.push(ss);
        while (!q.empty()) {
            int u = q.front();
            VIS[u] = 0;
            q.pop();
            for (int i = HD[u]; i != -1; i = NXT[i]) {
                int v = TO[i];
                if (DIS[v] > DIS[u] + V[i]) {
                    DIS[v] = DIS[u] + V[i];
                    if (!VIS[v]) {
                        VIS[v] = 1;
                        q.push(v);
                    }
                }
            }
        }
        return DIS[tt];
    }
     
    int main() {
        memset(HD, -1, sizeof (HD));
        scanf("%d%d%d%d%d", &n, &k, &a, &b, &c);
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                scanf("%d", &MAP[i][j]);
        tt = 200010;
        for (int x = 1; x <= n; ++x) {
            for (int y = 1; y <= n; ++y) {
                for (int i = k; i >= 0; --i) {
                    tot = mk(x, y, i);
                    if (x == 1 && y == 1 && i == k)
                        ss = tot;
                    if (x == n && y == n)
                        add(tot, tt, 0);
                    if (i != k)
                        if (MAP[x][y]) add(tot, mk(x, y, k), a);
                        else add(tot, mk(x, y, k), a + c);  
                    if (i != 0) {
                        if (MAP[x][y] && i != k) continue; //注意避开这种情况
                        if (x != 1)
                            add(tot, mk(x - 1, y, i - 1), b);
                        if (y != 1)
                            add(tot, mk(x, y - 1, i - 1), b);
                        if (x != n)
                            add(tot, mk(x + 1, y, i - 1), 0);
                        if (y != n)
                            add(tot, mk(x, y + 1, i - 1), 0);
                    }
                }
            }
        }
        printf("%d
    ", spfa());
        return 0;
    }
    
  • 相关阅读:
    关于VGG网络的介绍
    nvidia-docker 安装
    test
    ARTS-S EN0002-London HIV patient's remission spurs hope for curing AIDS
    ARTS-S EN0001-In tech race with China, US universities may lose a vital edge
    ARTS-S Why do India and Pakistan keep fighting over Kashmir?
    ARTS-S sed指定行添加
    ARTS-S linux查看进程打开的文件数
    ARTS-S centos查看端口被哪个进程占用
    ARTS-S centos修改hostname
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7434599.html
Copyright © 2020-2023  润新知