Welcome to my Uva catalogue https://blog.csdn.net/richenyunqi/article/details/81149109
Title Description
Analysis of title
In a race, there are n (n ≤ 300) intersections and m (m ≤ 50000) one-way roads. The interesting thing is that every road is closed periodically. Each path is represented by five integers u,v, a,b,t (1 ≤ u,v ≤ n,1 ≤ a,b,t ≤ 105), (1 ≤ u,v ≤ n,1 ≤ a,b,t ≤ 105), (1 ≤ u,v ≤ n,1 ≤ a,b,t ≤ 105), indicating that the starting point is u, the ending point is v, and the passing time is T seconds. In addition, this path will turn on a second, then turn off b second, then turn on a second, and so on. When the game begins, each road just opens. Your car must enter the road when it's open and leave before it's closed (it doesn't take time to get in and out of the road, so you can enter at the moment of opening and leave at the moment of closing).
Your task is to start from s and arrive at the destination t (1 ≤ s,t ≤ n) (1 ≤ s,t ≤ n) (1 ≤ s,t ≤ n) as early as possible. The start and end points of a road will not be the same, but there may be two roads with the same start and end points.
Algorithm design
Using Dijkstra algorithm, we should consider the waiting time when calculating the edge weight of a node u.
C++ code
#include<bits/stdc++.h> using namespace std; struct Edge{ int from,to,cost,open,close; Edge(int f,int t,int o,int clo,int c):from(f),to(t),open(o),close(clo),cost(c){} }; const int MAXV=305; vector<Edge>edges; vector<int>graph[MAXV]; int n,m,s,t,dis[MAXV]; int arriveNext(int arrive,const Edge&e){//Calculate the time from arrival at the beginning of road e arrival at the end of road e int temp=arrive%(e.open+e.close); if(temp+e.cost<=e.open) return arrive+e.cost; return arrive+e.open+e.close-temp+e.cost; } void Dijkstra(){ using pii=pair<int,int>; priority_queue<pii,vector<pii>,greater<pii>>pq;//first member of pii stores dis, second member stores node number fill(dis,dis+MAXV,INT_MAX); dis[s]=0; pq.push({0,s}); while(!pq.empty()){ pii p=pq.top(); pq.pop(); if(dis[p.second]!=p.first) continue; for(int i:graph[p.second]){ Edge&e=edges[i]; int arrive=arriveNext(dis[p.second],e);//Time to the end of road e if(dis[e.to]>arrive){ dis[e.to]=arrive; pq.push({dis[e.to],e.to}); } } } } int main(){ for(int ii=1;~scanf("%d%d%d%d",&n,&m,&s,&t);++ii){ edges.clear(); fill(graph,graph+n+1,vector<int>()); while(m--){ int u,v,a,b,t; scanf("%d%d%d%d%d",&u,&v,&a,&b,&t); if(t>a)//If it takes longer to pass the road than the opening time of the road, ignore the road directly continue; graph[u].push_back(edges.size()); edges.push_back(Edge(u,v,a,b,t)); } Dijkstra(); printf("Case %d: %d\n",ii,dis[t]); } return 0; }