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; }