d[u]是从s出发到u的最早时刻。
早到不会反而晚出发,即越早到越好。
Dijkstra改编一下,d[v]=d[u]+DIST,DIST是从u到v需要的时间,包括等待和路上的时间。讨论清楚DIST即可。
开放时间小于通过时间的边可以直接无视。
代码
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
#define maxn 310
using namespace std;
typedef long long ll;
const ll INF=0x3fffffff;
struct Edge
{
ll from,to,a,b,dist;
Edge(ll u,ll v,ll a,ll b,ll d):from(u),to(v),dist(d)
{
this->a=a;
this->b=b;
}
};
struct HeapNode
{
ll d,u;
bool operator < (const HeapNode& rhs) const
{
return d>rhs.d;
}
};
struct Dijkstra
{
ll n,m;
vector<Edge>edges;
vector<ll>G[maxn];
bool done[maxn];
ll d[maxn];
ll p[maxn];
void init(ll n)
{
this->n=n;
for(int i=0;i<n;i++) G[i].clear();
edges.clear();
}
void AddEdge(ll from,ll to,ll a,ll b,ll dist)
{
edges.push_back(Edge(from,to,a,b,dist));
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(ll s)
{
priority_queue<HeapNode>Q;
for(int i=1;i<=n;i++) d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
Q.push((HeapNode){0,s});
while(!Q.empty())
{
HeapNode x=Q.top();Q.pop();
ll u=x.u;
if(done[u]) continue;
done[u]=true;
for(unsigned int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
ll q=d[e.from]/(e.a+e.b);
ll r=d[e.from]%(e.a+e.b);
ll DIST;
if(e.a-r<e.dist) DIST=(q+1)*(e.a+e.b)+e.dist;
else DIST=d[e.from]+e.dist;
if(d[e.to]>DIST)
{
d[e.to]=DIST;
p[e.to]=G[u][i];
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
};
ll kase;
ll n,m,s,t;
int main()
{
while(scanf("%I64d %I64d %I64d %I64d",&n,&m,&s,&t)!=EOF)
{
Dijkstra D;
D.init(n);
for(int i=0;i<m;i++)
{
ll u,v,a,b,t;
scanf("%I64d %I64d %I64d %I64d %I64d",&u,&v,&a,&b,&t);
if(a>=t) D.AddEdge(u,v,a,b,t);
}
D.dijkstra(s);
printf("Case %lld: %lld\n",++kase,D.d[t]);
}
return 0;
}