• 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
  • 相关阅读:
    函数的定义
    函数加载的过程
    js中的return
    快速排序
    冒泡排序
    数组的案例
    正睿暑期培训day3考试
    bzoj2115 Xor
    luogu4570 元素
    bzoj4827 Hnoi2017 礼物
  • 原文地址:https://www.cnblogs.com/xiaobaibuhei/p/3326540.html
Copyright © 2020-2023  润新知