H - Funny Car Racing
H - Funny Car Racing
Time Limit:1000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Description
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 first 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 five 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 Outpu
Case 1: 20
Case 2: 9
//这题的意思是:第一行4个整数 n,m,s,t . 1 < n < 300 , 1 < m < 50000 , 1 <= s , t <= n , n 是点的个数,m 是有向边的个数,s 是起点,t 是终点
第二行五个整数 u , v , a , b , t ,说明有向边的起点,终点,这条边开启的时间,关闭的时间,通过需要的时间。这题简化了,通过这条边的条件是在关闭之前过去,不然就等到下个轮回再过去。显然t>a就不可能过去了,这数据应舍弃
//这题,是这个星期,完全没看别人的自己做出来的第一个题,对于刚学图论的有点难度。其实不难.
//spfa算法 0kb 50ms
1 #include <cstdio>
2 #include <cstring>
3 #include <queue>
4 using namespace std;
5
6 #define MAXN 500005
7 #define inf 0xfffffff
8
9 struct Bian
10 {
11 int e;
12 int a,b,t;
13 int next;
14 }bian[MAXN];
15
16 int headlist[305];
17 int d[305];
18 int vis[305];//其实我真不知道这个有什么用,不加也能过,有时候还能更快,但是每次看到spfa算法都加上我就加上了
19 int Case=0;
20
21 int check(int time,Bian x)//通过这条边需要的时间
22 {
23 int k=time%(x.a+x.b);
24 if (k+x.t<=x.a)
25 {
26 return x.t;
27 }
28 return x.a+x.b-k+x.t;
29 }
30
31 void spfa(int n,int m,int star,int end)
32 {
33 queue<int> Q;
34 int i,x,v,y;
35 for (i=1;i<=n;i++)
36 {
37 d[i]=inf;
38 vis[i]=0;
39 }
40 d[star]=0;
41 Q.push(star);
42 while (!Q.empty())
43 {
44 x=Q.front();
45 Q.pop();
46 vis[x]=0;
47 for (i=headlist[x];i!=-1;i=bian[i].next)
48 {
49 v=bian[i].e;
50 y=check(d[x],bian[i]);
51 if (d[v]>d[x]+y)
52 {
53 d[v]=d[x]+y;
54 if (!vis[v])
55 {
56 vis[v]=1;
57 Q.push(v);
58 }
59 }
60 }
61 }
62 printf("Case %d: %d\n",++Case,d[end]);
63 }
64
65 int main()
66 {
67 int n,m,s,e;
68 int u,v,a,b,t;
69 int i;
70 while (scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)
71 {
72 for (i=1;i<=n;i++)
73 headlist[i]=-1;
74
75 for (i=1;i<=m;i++)
76 {
77 scanf("%d%d%d%d%d",&u,&v,&a,&b,&t);
78 if (t>a) continue;
79 bian[i].e=v;
80 bian[i].a=a;
81 bian[i].b=b;
82 bian[i].t=t;
83 bian[i].next=headlist[u];//这叫邻接表吧
84 headlist[u]=i;
85 }
86 spfa(n,m,s,e);
87 }
88 return 0;
89 }