UvA 12661 Funny Car Racing (最短路)

There is a funny car racing in a city with n junctions and m directed roads.
The funny part is: each road is open and closed periodically. Each road is associate with two
integers (a; b), that means the road will be open for a seconds, then closed for b seconds, then open for
a seconds. . . All these start from the beginning of the race. You must enter a road when it‘s open, and
leave it before it‘s closed again.
Your goal is to drive from junction s and arrive at junction t as early as possible. Note that you
can wait at a junction even if all its adjacent roads are closed.
Input
There will be at most 30 test cases. The rst line of each case contains four integers n, m, s, t
(1 n 300, 1 m 50;000, 1 s; t n). Each of the next m lines contains ve integers u, v, a,
b, t (1 u; v n, 1 a; b; t 105
), that means there is a road starting from junction u ending with
junction v. It‘s open for a seconds, then closed for b seconds (and so on). The time needed to pass this
road, by your car, is t. No road connects the same junction, but a pair of junctions could be connected
by more than one road.
Output
For each test case, print the shortest time, in seconds. It‘s always possible to arrive at t from s.
Sample Input
3 2 1 3
1 2 5 6 3
2 3 7 7 6
3 2 1 3
1 2 5 6 3
2 3 9 5 6
Sample Output
Case 1: 20
Case 2: 9

题意:一个有向图,有M条路,每条路从u到v,并且,这条路每次开通a个单位时间,然后关闭b个单位时间,再开通a个单位时间......通过这条路的时间是t个单位时间,求起点s到终点t的最短时间

分析:最短路,只是说,在松弛的时候要注意

1、这条路如果通过的时间 t>a 的话,则这条路是不能通过的

2、如果到达下一个点剩下的时间 res<t  的话,还要算上等待的时间,这就相当于,延长的通过的时间。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<stdlib.h>
#include<algorithm>
#define LL __int64
#define FIN freopen("in.txt","r",stdin)
using namespace std;
const int MAXN=300+5;
const int INF=0x3f3f3f3f;
int n,m,s,t;
struct EDGE
{
    int v,t,a,b;
    EDGE(int a,int b,int c,int d): v(a),a(b),b(c),t(d){ }
};
vector<int> G[MAXN];
vector<EDGE> edge;
int d[MAXN];
int inq[MAXN];

void spfa()
{
    for(int i=0;i<=n;i++) d[i]=INF;
    d[s]=0;
    memset(inq,0,sizeof(inq));
    queue<int> Q;
    Q.push(s);
    inq[s]=1;
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        inq[u]=0;
        for(int i=0;i<G[u].size();i++)
        {
            EDGE tmp=edge[G[u][i]];
            int v=tmp.v,a=tmp.a,b=tmp.b,t=tmp.t;
            if(t>a) continue;
            int res=d[u]%(a+b);
            if(res+t<=a)
            {
                if(d[u]+t<d[v])
                {
                    d[v]=d[u]+t;
                    if(!inq[v]) {Q.push(v);inq[v]=1;}
                }
            }
            else
            {
                int num=d[u]+(a+b)-res+t;
                if(num<d[v])
                {
                    d[v]=num;
                    if(!inq[v]) {Q.push(v);inq[v]=1;}
                }
            }
        }
    }
}
int main()
{
    int Case=0;
    while(scanf("%d %d %d %d",&n,&m,&s,&t)!=EOF)
    {
        int tot=0;
        edge.clear();
        for(int i=0;i<=n;i++) G[i].clear();
        while(m--)
        {
            int u,v,a,b,t;
            scanf("%d %d %d %d %d",&u,&v,&a,&b,&t);
            edge.push_back(EDGE(v,a,b,t));
            G[u].push_back(tot++);
        }
        spfa();
        printf("Case %d: %d\n",++Case,d[t]);
    }
    return 0;
}

时间: 2024-12-12 23:02:47

UvA 12661 Funny Car Racing (最短路)的相关文章

UVA 12661 Funny Car Racing 有趣的赛车比赛(单源最短路,SSSP,变形)

题意:赛道有n个交叉点,和m条单向路径(有重边),每条路都是周期性关闭的,且通过仍需一段时间.在比赛开始时,所有道路刚好打开,选择进入该道路必须满足“在打开的时间段进入,在关闭之前出来”,即不可在路上逗留,但是可以在交叉点逗留.问到达终点的时间要多少? 思路:最短路,而且正权,用Dijkstra+优先队列够了.主要的难点在计算是否可以进入该路段,画图清晰点. 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define pii pair

[题解]UVa 12661 Funny Car Racing - spfa

很简单的一道最短路问题.分情况处理赛道的打开和关闭. Code 1 /** 2 * UVa 3 * Problem#12661 4 * Accepted 5 * Time:50ms 6 */ 7 #include<iostream> 8 #include<fstream> 9 #include<sstream> 10 #include<cstdio> 11 #include<cstdlib> 12 #include<cstring>

UVA 12661 Funny Car Racing

E - Funny Car Racing Time Limit:1000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu There is a funny car racing in a city with n junctions and m directed roads. The funny part is: each road is open and closed periodically. Each road is associ

UVa 12661 Funny Car Racing (dijkstra)

题意:给定一个有向图,每条路有5个整数修饰,u, v, a, b, t,表示起点为u,终点为v,打开时间a,关闭时间为b,通过时间为t,打开关闭是交替进行的, 问你从s到t最短时间是多少. 析:使用dijkstra算法,从每个结点出发,求最短路,并维护时间的最小值,这个可以用优先队列,然后考虑能不能通过这条路,如果t<a,可以在输入时处理. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include

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秒,

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 #

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 - 1416 Warfare And Logistics (最短路)

Description The army of United Nations launched a new wave of air strikes on terroristforces. The objective of the mission is to reduce enemy's logistical mobility. Each airstrike will destroy a path and therefore increase the shipping cost of the sh

UVA 116 Unidirectional TSP(DP最短路字典序)

Description  Unidirectional TSP  Background Problems that require minimum paths through some domain appear in many different areas of computer science. For example, one of the constraints in VLSI routing problems is minimizing wire length. The Travel