一道比较基础的最短路问题,和普通最短路的不同之处在于每条道路会开启a时间,关闭b时间的循环 。那么只需要在dijkstra算法中利用d[u]稍微改动一下就行了 。
两种情况:1 可以直接通过该条道路 。 2 需要等一会才能通过 。 当然还有可能无论如何都不能通过 。
细节参见代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 305; const ll INF = 10000000000000; const int maxm = 50000 + 5; int n,m,s,cnt,kase = 0,t,done[maxn]; ll d[maxn]; struct Node { int from,to,a,b,d; Node(int from=0,int to=0,int a=0,int b=0,int d=0):from(from),to(to),a(a),b(b),d(d) {} }e[maxn*maxn],cur ; vector<int> g[maxn]; struct heapNode{ int d,u; bool operator < (const heapNode& rhs) const { return d > rhs.d; } }; ll dijkstra(int s) { priority_queue<heapNode> q; for(int i=1;i<=n;i++) d[i] = INF , done[i] = 0; d[s] = 0; q.push((heapNode){0,s}); while(!q.empty()) { heapNode x = q.top(); q.pop(); int u = x.u; if(u == t) return d[u]; if(done[u]) continue; done[u] = true; for(int i=0;i<g[u].size();i++) { Node& ed = e[g[u][i]]; int v = d[u]%(ed.a+ed.b); if(ed.a-v>=ed.d) { if(d[ed.to] > d[u] + ed.d) { d[ed.to] = d[u] + ed.d; q.push((heapNode){d[ed.to],ed.to}); } } else if(ed.d <= ed.a) { if(d[ed.to] > d[u] + ed.d + ed.a - v + ed.b) { d[ed.to] = d[u] + ed.d + ed.a - v + ed.b; q.push((heapNode){d[ed.to],ed.to}); } } } } return -1; } int main() { while(~scanf("%d%d%d%d",&n,&m,&s,&t)) { cnt = 0; for(int i=1;i<=n;i++) g[i].clear(); for(int i=1;i<=m;i++) { scanf("%d%d%d%d%d",&cur.from,&cur.to,&cur.a,&cur.b,&cur.d); e[cnt] = cur; g[cur.from].push_back(cnt++); } ll ans = dijkstra(s); printf("Case %d: %lld\n",++kase,ans); } return 0; }