UVa 10801

  题目大意:一座楼有100层,编号0-99,有n个电梯,每个电梯有不同的速度,并且只在指定的楼层停,在某一层如果有多个电梯停,在两个电梯间转移需要1分钟,求出从0层出发到达k层的所用的最短时间。

  本来是正常的单源最短路问题,可是电梯转移花费的时间使得问题复杂了。刚开始是把一个节点扩展成两个节点,一个进一个出,在进出两个节点间加上60s的开销,纠结的好久才憋出来(犯了好多错误...浪费了好长时间),结果却WA了,用别人的测试用例结果也对,忽然就想到可能最终要到0层(写代码时考虑到了,可是认为不会这么干,也就没多写),处理完0之后,就好了...-_-||

 1 #include <cstdio>
 2 #include <vector>
 3 #include <cstring>
 4 #include <cctype>
 5 using namespace std;
 6 #define MAXN 210
 7 #define INF 1e8
 8 
 9 int G[MAXN][MAXN], dist[MAXN];
10 bool vis[MAXN];
11 
12 int main()
13 {
14 #ifdef LOCAL
15     freopen("in", "r", stdin);
16 #endif
17     int n, k;
18     int time[10];
19     while (scanf("%d%d", &n, &k) != EOF)
20     {
21         for (int i = 0; i < n; i++)
22             scanf("%d", &time[i]);
23         getchar();
24         for (int i = 0; i < 200; i++)
25             for (int j = 0; j < 200; j++)
26                 G[i][j] = INF;
27         for (int i = 0; i < 100; i++)
28             G[i*2][i*2+1] = G[i*2+1][i*2] = 60;
29         for (int i = 0; i < n; i++)
30         {
31             char str[10000];
32             gets(str);
33             vector<int> v;
34             int len = strlen(str);
35             for (int j = 0; j < len; j++)
36             {
37                 if (isdigit(str[j]))
38                 {
39                     int t = str[j] - '0';
40                     j++;
41                     while (j < len && isdigit(str[j]))
42                     {
43                         t = t * 10 + str[j] - '0';
44                         j++;
45                     }
46                     v.push_back(t);
47                 }
48             }
49             for (int j = 0; j < v.size(); j++)
50                 for (int p = j+1; p < v.size(); p++)
51                 {
52                     int x = v[j], y = v[p];
53                     G[2*x+1][2*y] = G[2*y+1][2*x] = min(G[2*x+1][2*y], (y-x)*time[i]);
54                 }
55         }
56         memset(vis, 0, sizeof vis);
57         for (int i = 0; i < 200; i++)
58             dist[i] = INF;
59         dist[1] = 0;
60         if (k)  k *= 2;
61         else  k = 1;
62         for (int i = 0; i < 200; i++)
63         {
64             int u, lmin = INF;
65             for (int j = 0; j < 200; j++)
66                 if (!vis[j] && dist[j] <= lmin)
67                 {
68                     lmin = dist[j];
69                     u = j;
70                 }
71             vis[u] = 1;
72             if (u == k)  break;
73             for (int j = 0; j < 200; j++)
74                 dist[j] = min(dist[j], dist[u]+G[u][j]);
75         }
76         if (dist[k] != INF)  printf("%d
", dist[k]);
77         else  printf("IMPOSSIBLE
");
78     }
79     return 0;
80 }
View Code

  后来看到可以不用这么麻烦,也是,上面那个代码构图时考虑了几次才对了。正常构图,在算权重的时候加上60就可以了(从0扩展出来的不用加60)。

 1 #include <cstdio>
 2 #include <vector>
 3 #include <queue>
 4 using namespace std;
 5 #define MAXN 110
 6 #define INF 1e9
 7 #define N 100
 8 typedef pair<int, int> ii;
 9 typedef vector<ii> vii;
10 
11 int G[MAXN][MAXN];
12 int time[10];
13 
14 int main()
15 {
16 #ifdef LOCAL
17     freopen("in", "r", stdin);
18 #endif
19     int n, k;
20     while (scanf("%d%d", &n, &k) != EOF)
21     {
22         for (int i = 0; i < n; i++)
23             scanf("%d", &time[i]);
24         for (int i = 0; i < N; i++)
25             for (int j = 0; j < N; j++)
26                 G[i][j] = INF;
27         for (int i = 0; i < n; i++)
28         {
29             vector<int> v;
30             do
31             {
32                 int x;
33                 scanf("%d", &x);
34                 v.push_back(x);
35             } while (getchar() != '
');
36             for (int p = 0; p < v.size(); p++)
37                 for (int q = p+1; q < v.size(); q++)
38                 {
39                     int x = v[p], y = v[q];
40                     G[x][y] = G[y][x] = min(G[x][y], (y-x)*time[i]);
41                 }
42         }
43         vector<int> dist(N, INF);
44         dist[0] = 0;
45         priority_queue<vii, vector<ii>, greater<ii> > pq;
46         pq.push(ii(0, 0));
47         while (!pq.empty())
48         {
49             ii top = pq.top();
50             pq.pop();
51             int d = top.first, u = top.second;
52             if (u == k)  break;
53             if (d == dist[u])
54                 for (int v = 0; v < N; v++)
55                 {
56                     if (u == 0)
57                     {
58                         if (dist[u] + G[u][v] < dist[v])
59                         {
60                             dist[v] = dist[u] + G[u][v];
61                             pq.push(ii(dist[v], v));
62                         }
63                     }
64                     else
65                     {
66                         if (dist[u] + G[u][v] + 60 < dist[v])
67                         {
68                             dist[v] = dist[u] + G[u][v] + 60;
69                             pq.push(ii(dist[v], v));
70                         }
71                     }
72                 }
73         }
74         if (dist[k] != INF) printf("%d
", dist[k]);
75         else  printf("IMPOSSIBLE
");
76     }
77     return 0;
78 }
View Code
原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3326540.html