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 }
View Code

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2016-07-28 18:43  happy_codes  阅读(207)  评论(0编辑  收藏  举报