UVA 10801 Lift Hopping

算是一道需要动脑筋的最短路问题了,关键在于建图部分,对于n个电梯中每一个都要经过cnt个楼层,a[0],a[1],a[2],a[3],a[4],......a[cnt-1],那么对于任意两个楼层a[j],a[l],都需要建立一条a[j]到a[l]的边,以及另一条反向边。而且为了表示所属的电梯,另外用一个数组tag[e]表示边e所属的电梯,当tag[e1]!=tag[e2],应该在时间上加上60s。然后利用dijsktra+优先队列即可。

最近感觉做acm题是真真的开始入门了,不过接触到的算法,是在是少,一步一步慢慢学精吧。坚持做到每天独立的切几题,这样的成就感一定能够使得我越走越远。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #define MAXN 200
 5 #define MAXM 30000
 6 #define INF 1000000000
 7 
 8 using namespace std;
 9 typedef pair<int, int> pii;
10 
11 int first[MAXN], T[10], a[MAXN], d[MAXN], pa[MAXN];
12 int next[MAXM], u[MAXM], v[MAXM], w[MAXM], tag[MAXM];
13 int i, n, k, cnt, e;
14 
15 void add_edge(int from, int to, int c)
16 {
17     u[e] = from;
18     v[e] = to;
19     next[e] = first[from];
20     w[e] = c;
21     tag[e] = i;
22     first[from] = e++;
23 }
24 void read_graph(void)
25 {
26     for(int j = 0; j < cnt; j++)
27         for(int l = j + 1; l < cnt; l++)
28     {
29         add_edge(a[j], a[l],(a[l] - a[j]) * T[i]);
30         add_edge(a[l], a[j],(a[l] - a[j]) * T[i]);
31     }
32 }
33 int cmp(int e1, int e2)
34 {
35     if(e1 == -1)
36         return 0;
37     if(tag[e1] == tag[e2])
38         return 0;
39     return 60;
40 }
41 priority_queue<pii, vector<pii>, greater<pii> > q;
42 
43 int main(void)
44 {
45     while(~scanf("%d%d", &n, &k))
46     {
47         char ch;
48         e = 0;
49         memset(first, -1, sizeof(first));
50         memset(pa, -1, sizeof(pa));
51         for(i = 1; i <= n; i++)
52             scanf("%d", T + i);
53         for(i = 1; i <= n; i++)
54         {
55             cnt = 0;
56             while(1)
57             {
58                 scanf("%d%c", &a[cnt], &ch);
59                 cnt++;
60                 if(ch == '\n')
61                 {
62                     read_graph();
63 //                   printf("%d\n", cnt);
64                     break;
65                 }
66             }
67         }
68 //      printf("%d\n", e);
69         for(int j = 0; j < 100; j++)
70             d[j] = INF;
71         d[0] = 0;
72         q.push(make_pair(d[0],0));
73         while(!q.empty())
74         {
75             pii u = q.top();
76             q.pop();
77             int x = u.second;
78             if(d[x] != u.first)
79                  continue;
80               for(int ee = first[x]; ee != -1; ee = next[ee])
81                 if(d[v[ee]] > d[x] + w[ee] + cmp(pa[x],ee))
82                 {
83                     d[v[ee]] = d[x] + w[ee]  + cmp(pa[x],ee);
84 //                    printf("%d\n", cmp(pa[ee], ee));
85                     q.push(make_pair(d[v[ee]],v[ee]));
86                     pa[v[ee]] = ee;
87                 }
88         }
89         if(d[k] == INF)
90             puts("IMPOSSIBLE");
91         else printf("%d\n",d[k]);
92     }
93     return 0;
94 }

 

你可能感兴趣的:(ping)