UVa 12661 - Funny Car Racing(Dijkstra)

链接:

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\n", cases, Dijkstra(start, finish));
64     }
65     return 0;
66 }

原文地址:https://www.cnblogs.com/hkxy125/p/9545368.html

时间: 2024-10-30 04:31:50

UVa 12661 - Funny Car Racing(Dijkstra)的相关文章

UVA - 12661 Funny Car Racing (Dijkstra算法)

题目: 思路: 把时间当做距离利用Dijkstra算法来做这个题. 前提:该结点e.c<=e.a,k = d[v]%(e.a+e.b); 当车在这个点的1处时,如果在第一个a这段时间内能够通过且更小的话,那时间就更新为d[e.to] = d[v]+e.a-k+e.c; 当车在这个点的1处时,如果在第一个a这段时间内不能通过,但等待之后再通过时间更短的话,那时间更新为d[e.to]=d[v]+e.a+e.b-k+e.to 如果在这个点的2处时,如果在等待之后通过的时间更短的话,时间更新和第二种情况

UVa 12661 Funny Car Racing【 dijkstra 】

题意:给出n个点,m条路,每条路用5个整数表示u,v,a,b,t u表示这条路的起点,v表示终点,a表示打开时间,b表示关闭时间,t表示通过这条道路需要的时间 看的紫书,因为边权不再仅仅是路上的时间,还需要处理一下是否需要等待 如果不需要等待的话,这条路上的权值就为t 如果需要等待的话,这条路的权值就为t+wait 再用dijkstra就可以了 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #

最短路径算法——迪杰斯特拉算法(Dijkstra)

图结构中应用的最多的就是最短路径的查找了,关于最短路径查找的算法主要有两种:迪杰斯特拉算法(Dijkstra)和Floyd算法. 其中迪杰斯特拉算法(Dijkstra)实现如下: 原理就是不断寻找当前的最优解: void main() { int V[Max][Max]={0,8,32,Infinity,Infinity, 12,0,16,15,Infinity, Infinity,29,0,Infinity,13, Infinity,21,Infinity,0,7, Infinity,Infi

hdu 1874(Dijkstra )

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874 畅通工程续 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 27692    Accepted Submission(s): 10019 Problem Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路

Uva 10815-Andy&#39;s First Dictionary(串)

Problem B: Andy's First Dictionary Time limit: 3 seconds Andy, 8, has a dream - he wants to produce his very own dictionary. This is not an easy task for him, as the number of words that he knows is, well, not quite enough. Instead of thinking up all

UVA 10791 Minimum Sum LCM (数论)

LCM (Least Common Multiple) of a set of integers is defined as the minimum number, which is a multiple of all integers of that set. It is interesting to note that any positive integer can be expressed as the LCM of a set of positive integers. For exa

UVA 10375 Choose and divide(数论)

The binomial coefficient C(m,n) is defined as m! C(m,n) = -------- n!(m-n)! Given four natural numbers p, q, r, and s, compute the the result of dividing C(p,q) by C(r,s). The Input Input consists of a sequence of lines. Each line contains four non-n

uva:10700 - Camel trading(贪心)

题目:10700 - Camel trading 题目大意:给出一些表达式,表达式由数字和加号乘号组成,数字范围[1,20].这些表达式可能缺少了括号,问这样的表达式加上括号后能得到的最大值和最小值. 解题思路:因为这些数的都是正整数,所以可以用贪心.不然看出最大值就是先做完加法在做乘法,最小值就是先做乘法在做加法.注意这里的数值要用long long 因为比表达式的值可能会超过int. 代码: #include <stdio.h> #include <string.h> cons

poj1062昂贵的聘礼(Dijkstra**)

1 /* 2 题意: 物主有一个物品,价值为P,地位为L, 以及一系列的替代品Ti和该替代品所对应的"优惠"Vi 3 g[u][i] 表示的是u物品被i物品替换后的优惠价格!(u>0, i>0) 4 g[u][0]表示不用替换该物品的实际价格 ! 5 d[0]表示的是第一个物品经过一系列的物品替换之后的最少优惠价格! 6 7 思路:每当我们通过Dijkstra算法得到离源点(1)最近的距离的节点 p的时候(也就是1...pre[p], p)这条 8 路径上的物品互相替换后得