CSU

来源:互联网 发布:数据库分页查询sql 编辑:程序博客网 时间:2024/05/01 03:14

1333: Funny Car Racing

        Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 526     Solved: 125    

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 (ab), 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 31 2 5 6 32 3 7 7 63 2 1 31 2 5 6 32 3 9 5 6

Sample Output

Case 1: 20Case 2: 9

Hint

Source

湖南省第九届大学生计算机程序设计竞赛

spfa,计算等待时间,看加上等待时间后是否能松弛,下面说下如何计算等待时间

分隔线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


a为通道开启时间,b为关闭时间

边的权值(以下简称w)大于a的时候直接跳过,这点不用多说了,怎么也走不过去

关键在用到其他点松弛的时候,设用到的点为t,设cc=dis[t]%(a+b)取余,

得到cc为到达t点时,此时的时间在(a+b)时间轴上的位置,

然后分别讨论几种情况

cc<a:

(1)cc+w<=a  直接可以通过,判断是否可以松弛

(2)cc+w>a   此时通道关闭,就需要等待了,

等待的时间为a+b-cc,加上等待时间后判断是否可以松弛

cc>a:

此时无论如何也要等待的,等待时间为a+b-cc,其余同上

#include <iostream>#include<string>#include<string.h>#include<stdio.h>#include<stdlib.h>#include<queue>#include<math.h>#include<algorithm>#define ll long long#define mem(a,b) memset(a,b,sizeof(a))#define inf 10000000000000;using namespace std;ll n,m,s,t;struct node{    ll u,v,a,b,w;}e[100005];ll first[305],nex[100005],dis[305];int vis[305];void sett(ll u,ll v,ll a,ll b,ll w,ll i){    e[i].u=u,e[i].v=v,e[i].a=a,e[i].b=b,e[i].w=w;    nex[i]=first[e[i].u];    first[e[i].u]=i;}void spfa(ll x,ll y){    for(ll i=1;i<=n;i++)        {            dis[i]=inf;            vis[i]=0;        }    dis[x]=0,vis[x]=1;    queue<ll>q;    q.push(x);    vis[x]=1;    while(!q.empty())    {        ll temp=q.front();        q.pop();        vis[temp]=0;        for(ll i=first[temp];i!=-1;i=nex[i])        {            ll v=e[i].v,a=e[i].a,b=e[i].b,w=e[i].w;            ll cc=dis[temp]%(a+b),tt;            if(w>a)continue;            if(cc<=a)            {                if((cc+w)<=a)                    tt=dis[temp]+w;                else                    tt=a-cc+b+w+dis[temp];            }            else                tt=dis[temp]+a+b-cc+w;                if(dis[v]>tt)                {                    dis[v]=tt;                    if(!vis[v])                    {vis[v]=1;                    q.push(v);}                }        }    }}int main(){    int q=1;    while(~scanf("%lld%lld%lld%lld",&n,&m,&s,&t))    {        ll u,v,a,b,w;        mem(first,-1);        for(ll i=1;i<=m;i++)        {            scanf("%lld%lld%lld%lld%lld",&u,&v,&a,&b,&w);            sett(u,v,a,b,w,i);        }        spfa(s,t);        printf("Case %d: %lld\n",q++,dis[t]);    }}






0 0
原创粉丝点击