zoukankan      html  css  js  c++  java
  • TYVJ2032 升降梯上

    Description:

    开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道、一辆停在轨道底部的电梯、和电梯内一杆控制电梯升降的巨大手柄。
    Nescafe 之塔一共有 N 层,升降梯在每层都有一个停靠点。手柄有 M 个控制槽,第 i个控制槽旁边标着一个数 Ci,满足 C1<C2<C3<„„<CM。如果 Ci>0,表示手柄扳动到该槽时,电梯将上升 Ci 层;如果 Ci<0,表示手柄扳动到该槽时,电梯将下降-Ci 层;并且一定存在一个 Ci=0,手柄最初就位于此槽中。注意升降梯只能在 1~N 层间移动,因此扳动到使
    升降梯移动到 1 层以下、N 层以上的控制槽是不允许的。电梯每移动一层,需要花费 2 秒钟时间,而手柄从一个控制槽扳到相邻的槽,需要花费1 秒钟时间。探险队员现在在 1 层,并且想尽快到达 N 层,他们想知道从 1 层到 N 层至少需要多长时间?

     

    Input:

    第一行两个正整数 NM
    第二行 M 个整数 C1C2„„CM

    Output:

    输出一个整数表示答案,即至少需要多长时间。若不可能到达输出-1

    思路:水题,将每一层的每个状态拆开连边,然后建一个超级源点与终点,连边即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    const int N = 30010, M = 1e6 + 10, INF = 1e9;
    typedef pair<int,int> P; 
    
    int head[N], now;
    struct edges{
        int to, next, w;
    }edge[M<<1];
    void add(int u,int v, int w){ edge[++now] = {v, head[u], w}; head[u] = now;}
    
    int n, m, c[N], dis[N];
    int id(int x,int y){ return (x - 1) * m + y;}
    void dij(int s){
        priority_queue<P,vector<P>, greater<P> > heap;
        memset(dis,0x3f, sizeof(dis));
        dis[s] = 0;
        heap.push(P(0, s));
        while(!heap.empty()){
            P tmp = heap.top(); heap.pop();
            int x = tmp.second;
            if(tmp.first > dis[x]) continue;
            for(int i = head[x]; i; i = edge[i].next){
                int v = edge[i].to;
                if(dis[v] > dis[x] + edge[i].w){
                    dis[v] = dis[x] + edge[i].w;
                    heap.push(P(dis[v], v));
                }
            }
        }
        return ;
    }
    int main(){
        scanf("%d%d",&n, &m);
        int pos;
        for(int i = 1; i <= m; i++){
            scanf("%d",&c[i]);
            if(c[i] == 0) pos = i;
        }
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(j < m)  add(id(i, j), id(i, j + 1), 1);
                if(j > 1)  add(id(i, j), id(i, j - 1), 1);
                if(i + c[j] <= n && i + c[j] >= 1)
                  add(id(i, j), id(i + c[j], j), abs(c[j] * 2));
            }
        }
        for(int i = 1; i <= m; i++)
          add(id(n, i), n * m + 1, 0);
        dij(id(1, pos));
        if(dis[n * m + 1] > INF) puts("-1");
        else printf("%d
    ", dis[n * m + 1]);
        return 0;
    }
    View Code
  • 相关阅读:
    Debian 添加用户
    如何让安卓手机访问内网服务器?
    数据库权限
    CentOs
    批量导入sql文件。
    使用Navicat Premium连接mysql数据库
    git 合包
    linux 下文件打包
    git 分支管理
    gcc8.2安装
  • 原文地址:https://www.cnblogs.com/Rorshach/p/8724721.html
Copyright © 2011-2022 走看看