很巧妙的一道题目,主要考察的是迪杰斯特拉算法,但是要注意几个点:第一,通过某一条路的时间可能比该条路开放的时间要长,也就是说,不论怎么样,这条路是不能够通过的,所以就直接舍弃;第二,判断是否能够在合适的时间范围内通过需要用到取余的操作,同时如果能够在当前直接通过不需要等待与需要等待,这两种情况下对到达下一个节点的时间的计算是不一样的,这一部分要注意,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
class Edge{
public:
int from, to, open, close, time;
};
class Node{
public:
int length, id;
bool operator< (const Node& a) const{
return length > a.length;
}
};
class Solve{
public:
int n, m, s, t;
vector<Edge> edge;
vector<int> G[310];
const int Inf = 30000005;
int Dijkstra(){
priority_queue<Node,vector<Node>> q;
bool visit[310];
int dist[310];
for (int i = 0; i < 310; i++) dist[i] = Inf;
memset(visit, 0, sizeof(visit));
Node temp;
temp.id = s;
dist[s] = 0;
temp.length = 0;
q.push(temp);
while (!q.empty()){
temp = q.top();
q.pop();
if (visit[temp.id]) continue;
visit[temp.id] = true;
for (int i = 0; i < G[temp.id].size(); i++){
int ide = G[temp.id][i];
Node temp2;
int open = edge[ide].open, close = edge[ide].close, time = edge[ide].time;
if (time > open) continue;
int from = edge[ide].from, to = edge[ide].to;
temp2.id = to;
if (temp.length % (open + close) + time <= open){
temp2.length = temp.length+ time;
if (dist[to] > temp2.length){
dist[to] = temp2.length;
q.push(temp2);
}
}
else{
temp2.length = temp.length + open + close + time - temp.length % (open + close);
if (dist[to] > temp2.length){
dist[to] = temp2.length;
q.push(temp2);
}
}
}
}
return dist[t];
}
void Init(){
edge.clear();
for (int i = 0; i < 310; i++) G[i].clear();
for (int i = 0; i < m; i++){
Edge temp;
cin >> temp.from >> temp.to >> temp.open >> temp.close >> temp.time;
edge.push_back(temp);
G[temp.from].push_back(edge.size()-1);
}
}
int Deal(){
Init();
int ans = Dijkstra();
return ans;
}
};
int main(){
Solve a;
int Case = 0;
while (cin >> a.n >> a.m >> a.s >> a.t){
Case++;
int res = a.Deal();
cout << "Case " << Case << ": " << res << endl;
}
return 0;
}