P2032 「Poetize9」升降梯上
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道、一辆停在轨道底部的电梯、和电梯内一杆控制电梯升降的巨大手柄。
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层至少需要多长时间?
输入格式
第一行两个正整数N、M。
第二行M个整数C1、C2……CM。
输出格式
输出一个整数表示答案,即至少需要多长时间。若不可能到达输出-1。
测试样例1
输入
6 3
-1 0 2
输出
19
备注
手柄从第二个槽扳到第三个槽(0扳到2),用时1秒,电梯上升到3层,用时4秒。
手柄在第三个槽不动,电梯再上升到5层,用时4秒。
手柄扳动到第一个槽(2扳到-1),用时2秒,电梯下降到4层,用时2秒。
手柄扳动到第三个槽(-1扳倒2),用时2秒,电梯上升到6层,用时4秒。
总用时为(1+4)+4+(2+2)+(2+4)=19秒。
对于30% 的数据,满足1≤N≤10,2<=M<=5。
对于 100% 的数据,满足1≤N≤1000,2<=M<=20,-N<C1<C2<……<CM<N。
【题解】
(i - 1) * m + j - 1表示在第i层j槽处
连边Dijstra即可
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstdlib> 5 #include <cstring> 6 #include <queue> 7 #define max(a, b) ((a) > (b) ? (a) : (b)) 8 #define min(a, b) ((a) < (b) ? (a) : (b)) 9 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 10 11 const int INF = 0x3f3f3f3f; 12 const int MAXN = 1000 + 10; 13 const int MAXM = 20 + 5; 14 15 inline void read(int &x) 16 { 17 x = 0;char ch = getchar(), c = ch; 18 while(ch < ‘0‘ || ch > ‘9‘) c = ch, ch = getchar(); 19 while(ch <= ‘9‘ && ch >= ‘0‘) x = x * 10 + ch - ‘0‘, ch = getchar(); 20 if(c == ‘-‘)x = -x; 21 } 22 23 int n,m; 24 25 inline int number(int a, int b) 26 { 27 return (a - 1) * m + b - 1; 28 } 29 30 struct Edge 31 { 32 int u,v,w,next; 33 Edge(int _u, int _v, int _w, int _next){u = _u;v = _v;w = _w;next = _next;} 34 Edge(){} 35 }edge[MAXN * MAXM * MAXM * 4]; 36 int head[MAXN * MAXM * 2], cnt, c[MAXN]; 37 38 inline void insert(int a, int b, int c) 39 { 40 edge[++cnt] = Edge(a,b,c,head[a]); 41 head[a] = cnt; 42 } 43 44 struct Node 45 { 46 int node,w; 47 Node(int a, int b){node = a;w = b;} 48 Node(){} 49 }; 50 51 struct cmp 52 { 53 bool operator()(Node a, Node b) 54 { 55 return a.w > b.w; 56 } 57 }; 58 59 std::priority_queue<Node, std::vector<Node>, cmp> q; 60 int s, d[MAXN * MAXM * 2], b[MAXN * MAXM * 2]; 61 62 void dijstra() 63 { 64 memset(d, 0x3f, sizeof(d)); 65 d[s] = 0; 66 q.push(Node(s, 0)); 67 Node tmp; 68 int u,v; 69 while(q.size()) 70 { 71 tmp = q.top(), q.pop(); 72 if(b[tmp.node])continue; 73 u = tmp.node; 74 b[u] = 1; 75 for(register int pos = head[u];pos;pos = edge[pos].next) 76 { 77 v = edge[pos].v; 78 if(b[v])continue; 79 if(d[v] > d[u] + edge[pos].w) 80 { 81 d[v] = d[u] + edge[pos].w; 82 q.push(Node(v, d[v])); 83 } 84 } 85 } 86 } 87 88 int main() 89 { 90 read(n), read(m); 91 for(register int i = 1;i <= m;++ i) 92 { 93 read(c[i]); 94 if(c[i] == 0)s = number(1, i); 95 } 96 for(register int i = 1;i < n;++ i) 97 { 98 for(int j = 1;j <= m;++ j) 99 { 100 if(i + c[j] > 0 && i + c[j] <= n && c[j] != 0) 101 insert(number(i,j), number(i + c[j], j), abs(c[j]) * 2); 102 for(int k = 1;k <= m;++ k) 103 if(k != j) 104 insert(number(i, j), number(i, k), abs(j - k)); 105 } 106 } 107 dijstra(); 108 int ans = INF; 109 for(register int i = 1;i <= m;++ i) 110 ans = min(ans, d[number(n, i)]); 111 if(ans == INF)ans = -1; 112 printf("%d", ans); 113 return 0; 114 }
TYVJ2032