• UVa 12661


    链接:

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4399

    题意:

    在一个赛车比赛中,赛道有n(n≤300)个路口和m(m≤50000)条单向道路。有趣的是:每条路都是周期性关闭的。
    每条路用5个整数u, v, a, b, t表示(1≤u,v≤n,1≤a,b,t≤1e5),表示起点是u,终点是v,通过时间为t秒。
    另外,这条路会打开a秒,然后关闭b秒,然后再打开a秒,依此类推。当比赛开始时,每条道路刚刚打开。
    你的赛车必须在道路打开的时候进入该道路,并且在它关闭之前离开(可以在打开的瞬间进入,关闭的瞬间离开)。
    注意你的赛车可以在道路关闭的时候在路口等待它打开。没有道路连接同一个路口,但一对路口之间可能有多条道路。
    你的任务是从s出发,尽早到达目的地t(1≤s,t≤n)。

    分析:

    本题是一道最短路问题,但又和普通的最短路问题不太相同:花费的总时间并不是经过的每条边的通过时间之和,
    还要加上在每个点等待的总时间。仍然调用标准的Dijkstra算法,
    只是在计算一个结点u出发的边权时要考虑d[u](即从s出发达到u的最早时刻)。计算边权时分情况讨论一下即可。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #include <vector>
     5 using namespace std;
     6 
     7 struct Edge {
     8     int b, open, close, time;
     9 };
    10 struct HeapNode {
    11     int ver, dist;
    12     bool operator < (const HeapNode& that) const {
    13         return dist > that.dist;
    14     }
    15 };
    16 const int INF = 0x3f3f3f3f;
    17 const int UP = 300 + 5;
    18 int d[UP];
    19 bool done[UP];
    20 vector<Edge> edge[UP];
    21 
    22 int Dijkstra(int start, int finish) {
    23     memset(d, INF, sizeof(d));
    24     memset(done, false, sizeof(done));
    25     d[start] = 0;
    26     priority_queue<HeapNode> Q;
    27     Q.push((HeapNode){start, 0});
    28     while(!Q.empty()) {
    29         HeapNode f = Q.top();  Q.pop();
    30         int ver = f.ver;
    31         if(ver == finish) return f.dist;
    32         if(done[ver]) continue;
    33         done[ver] = true;
    34         for(int i = 0; i < edge[ver].size(); i++) {
    35             Edge& b = edge[ver][i];
    36             int progress = d[ver] % (b.open + b.close);
    37             if(progress + b.time <= b.open) {
    38                 if(d[b.b] > d[ver] + b.time) {
    39                     d[b.b] = d[ver] + b.time;
    40                     Q.push((HeapNode){b.b, d[b.b]});
    41                 }
    42             } else {
    43                 int need = d[ver] + b.time + b.open + b.close - progress;
    44                 if(d[b.b] > need) {
    45                     d[b.b] = need;
    46                     Q.push((HeapNode){b.b, need});
    47                 }
    48             }
    49         }
    50     }
    51     return d[finish];
    52 }
    53 
    54 int main() {
    55     int n, m, start, finish;
    56     for(int cases = 1; ~scanf("%d%d%d%d", &n, &m, &start, &finish); cases++) {
    57         for(int i = 1; i <= n; i++) edge[i].clear();
    58         for(int L, R, a, b, t, i = 0; i < m; i++) {
    59             scanf("%d%d%d%d%d", &L, &R, &a, &b, &t);
    60             if(t > a) continue;
    61             edge[L].push_back((Edge){R, a, b, t});
    62         }
    63         printf("Case %d: %d
    ", cases, Dijkstra(start, finish));
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    每日日报31
    每日日报30
    每日日报29
    《精益软件开发管理之道》阅读笔记03
    每日日报28
    ip地址访问vue项目
    eslint prettier vetur eslint
    线上环境去除console
    vue 多环境打包
    2申请高德地图key 初始化地图
  • 原文地址:https://www.cnblogs.com/hkxy125/p/9545368.html
Copyright © 2020-2023  润新知