zoukankan      html  css  js  c++  java
  • UVa 12661 (单源最短路) Funny Car Racing

    题意:

    有一个赛车跑道,可以看做一个加权有向图。每个跑道(有向边)还有一个特点就是,会周期性地打开a秒,然后关闭b秒。只有在赛车进入一直到出来,该跑道一直处于打开状态,赛车才能通过。

    开始时所有跑道处于刚打开的状态,求从起点到终点的最短时间。

    分析:

    设d[i]为起点到节点i的最短时间。

    和普通的单源最短路问题一样,只不过在进行松弛操作的时候分两种情况。松弛的前提是,赛道打开的时间不短于赛车通过的时间。

    1. 赛车从进入直到出跑道,一直是打开状态。则d[v] = min(d[v], d[u] + t)
    2. 赛道已经关闭或会在中途关闭,则只能等到下次刚刚打开时进入,因此有个等待时间。d[v] = min(d[v], d[u] + wait + t)
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 300 + 10;
     5 const int INF = 1000000000;
     6 
     7 struct Edge
     8 {
     9     int from, to, a, b, t;
    10     Edge(int u, int v, int a, int b, int t):from(u), to(v), a(a), b(b), t(t) {}
    11 };
    12 
    13 vector<Edge> edges;
    14 vector<int> G[maxn];
    15 bool inq[maxn];
    16 int n, m, s, t, d[maxn];
    17 
    18 void Init()
    19 {
    20     edges.clear();
    21     for(int i = 0; i < n; ++i) G[i].clear();
    22 }
    23 
    24 void AddEdge(int u, int v, int a, int b, int t)
    25 {
    26     edges.push_back(Edge(u, v, a, b, t));
    27     int m = edges.size();
    28     G[u].push_back(m-1);
    29 }
    30 
    31 void SPFA()
    32 {
    33     memset(inq, false, sizeof(inq));
    34     for(int i = 0; i < n; ++i) d[i] = INF;
    35     queue<int> Q;
    36     d[s] = 0; inq[s] = true; Q.push(s);
    37 
    38     while(!Q.empty())
    39     {
    40         int u = Q.front(); Q.pop();
    41         inq[u] = false;
    42         for(int i = 0; i < G[u].size(); ++i)
    43         {
    44             Edge& e = edges[G[u][i]];
    45             int v = e.to, a = e.a, b = e.b, t = e.t;
    46             if(a < t) continue;
    47             int now = d[u] % (a+b);
    48             if(now + t <= a)
    49             {//情况一
    50                 if(d[v] > d[u] + t)
    51                 {
    52                     d[v] = d[u] + t;
    53                     Q.push(v);
    54                     inq[v] = true;
    55                 }
    56             }
    57             else
    58             {//情况二
    59                 int wait = a + b - now;
    60                 if(d[v] > d[u] + wait + t)
    61                 {
    62                     d[v] = d[u] + wait + t;
    63                     Q.push(v);
    64                     inq[v] = true;
    65                 }
    66             }
    67         }
    68     }
    69 }
    70 
    71 int main()
    72 {
    73     //freopen("in.txt", "r", stdin);
    74 
    75     int kase = 0;
    76     while(scanf("%d%d%d%d", &n, &m, &s, &t) == 4)
    77     {
    78         s--; t--;
    79         Init();
    80         for(int i = 0; i < m; ++i)
    81         {
    82             int u, v, a, b, t;
    83             scanf("%d%d%d%d%d", &u, &v, &a, &b, &t);
    84             AddEdge(u-1, v-1, a, b, t);
    85         }
    86         SPFA();
    87         printf("Case %d: %d
    ", ++kase, d[t]);
    88     }
    89 
    90     return 0;
    91 }
    代码君
  • 相关阅读:
    年轻人要明白,职场里不只有晋升
    为什么我建议年轻人多出去走走?
    聊聊所谓的弹性工作制
    从零开始搭建Java开发环境第四篇:精选IDEA中十大提高开发效率的插件!
    从零开始搭建Java开发环境第三篇:最新版IDEA常用配置指南,打造你的最酷IDE
    ORACLE日期时间函数大全
    我做的 地税信息中心设备台账
    IE8 如何 不显示 选项 卡,直接在任务显示 各个页面?
    分析
    微信端的界面与后台之间的接口稳定性压力测试用什么工具比较好点
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4292128.html
Copyright © 2011-2022 走看看