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\n", ++kase, d[t]);
88     }
89
90     return 0;
91 }

代码君

时间: 2024-12-28 06:12:37

UVa 12661 (单源最短路) Funny Car Racing的相关文章

UVA 658 It&#39;s not a Bug, it&#39;s a Feature! (单源最短路,dijkstra+优先队列,变形,经典)

题意:有n个bug,有m个补丁,每个补丁有一定的要求(比如某个bug必须存在,某个必须不存在,某些无所谓等等),打完出来后bug还可能变多了呢.但是打补丁是需要时间的,每个补丁耗时不同,那么问题来了:要打多久才能无bug?(同1补丁可重复打) 分析: n<=20,那么用位来表示bug的话有220=100万多一点.不用建图了,图实在太大了,用位图又不好玩.那么直接用隐式图搜索(在任意点,只要满足转移条件,任何状态都能转). 但是有没有可能每个状态都要搜1次啊?那可能是100万*100万啊,这样出题

uva 10099 The Tourist Guide(单源最短路/spfa/dijkstra)

题目: 链接:点击打开链接 题意: 思路: 代码: #include <iostream> #include <cstring> #include <cstdio> using namespace std; int map[101][101]; void floyd(int n) { for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) map[i][j] = m

【算法系列学习】Dijkstra单源最短路 [kuangbin带你飞]专题四 最短路练习 A - Til the Cows Come Home

https://vjudge.net/contest/66569#problem/A http://blog.csdn.net/wangjian8006/article/details/7871889 邻接矩阵实现的单源最短路 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #include

Dijkstra算法 --- 单源最短路

Dijkstra算法适用于边权值为正的情况,可用于计算正权图上的单元最短路. 其伪代码如下: 设d[v0] = 0, 其他d[i] = INF 循环n次{ 在所有未标号的结点中,选取d值最小的结点x 给结点x加上永久标号 对于从x出发的所有边,执行松弛操作. } //松弛操作的伪代码如下: RELAX(u,v,w) if(u.d + w(u,v) < v.d){ v.d = w.d + w(u,v); pre[v] = u; } Dijkstra算法代码: /* Dijkstra 单源最短路算法

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数: #include<cstdio> #define maxn 10000000+10 using namespace std; int n,prime[5000001],num_prime=0,m; bool if_prime[maxn]; void euler(int limit) { for(int i=2;i<=limit;i++) { if(!if_prime[i]) prime[++num_prime]=i; for(int j=1;prime[j]*i<=l

利用分支限界法求解单源最短路(Dijkstra)问题

分支限界法定义:采用BFS算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按广度优先的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分支,不断重复这一过程,直到找到答案或者判定无解. 分支界限法常常用到优先队列来选择最佳扩展节点,有时也会用到普通队列,以先进先出为原则来进行筛选. 单源最短路问题定义:给定有向图和起点,寻找到达所有点的最短路径. 单源最短路的分支限界法概述:首先把节点加入优先队列,之后不断地从队列中取出最优扩展点,观察其可抵达的所有目标节点,若当前路径

单源最短路_SPFA_C++

当我们需要求一个点到其它所有点的最短路时,我们可以采用SPFA算法 代码特别好写,而且可以有环,但是不能有负权环,时间复杂度是O(α(n)n),n为边数,α(n)为n的反阿克曼函数,一般小于等于4 模板:http://www.cnblogs.com/hadilo/p/5934679.html 我感觉自己讲的不会很好,丢一个链接算了 算法详解:http://www.360doc.com/content/13/1208/22/14357424_335569176.shtml 伪代码是自己写的: 可以

HDU-4849 Wow! Such City! (单源最短路)

Problem Description Doge, tired of being a popular image on internet, is considering moving to another city for a new way of life. In his country there are N (2 ≤N≤ 1000) cities labeled 0 . . . N - 1. He is currently in city 0. Meanwhile, for each pa

【裸单源最短路:Dijkstra算法两种版本】hdu 1874 畅通工程续

Source : hdu 1874 畅通工程续 http://acm.hdu.edu.cn/showproblem.php?pid=1874 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很困扰. 现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离. Input 本题目包含多组数据,请处理到文件结束.