带权最短路。但松弛操作需要分类讨论,要考虑清楚。Bellman-Ford和Dijkstra速度差不多。
Run Time: 0.139s
#define UVa "LT11-11.12661.cpp" //Funny Car Racing
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>
#include<queue>
using namespace std;
//Global Variables. Reset upon Each Case!
typedef pair<int,int> Node;
const int maxn = 600+5, maxm = 500000+5, INF = 1<<30; //change#1: maxn
int n, m, s, t;
/
struct Edge {
int from, to, open, close, passtime;
Edge(int a1, int a2, int a3, int a4, int a5):
from(a1), to(a2), open(a3), close(a4), passtime(a5) {}
};
struct HeapNode {
int d, u;
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra {
vector<Edge> edges;
vector<int> G[maxn];
int d[maxn], vis[maxn];
void init() {
edges.clear();
for(int i = 0; i < maxn; i ++) G[i].clear();
}
void addEdge(int from, int to, int a, int b, int cost) {
edges.push_back(Edge(from, to, a, b, cost));
G[from].push_back(edges.size()-1);
}
bool update_dist(int& targ, int v, Edge& e) {
if(e.passtime > e.open) return false;
int T = e.open + e.close; //period
if(v%T + e.passtime > e.open)
v += T-(v%T);
if(targ > v+e.passtime) {
targ = v+e.passtime;
return true;
}
return false;
}
int SP(int src, int targ) {
memset(vis, 0, sizeof(vis));
memset(d, 0x3f, sizeof(d));
priority_queue<HeapNode> q;
q.push((HeapNode){d[src], src});
d[src] = 0;
while(!q.empty()) {
int x = q.top().u; q.pop();
if(vis[x]) continue;
vis[x] = 1;
if(x == targ) break;
for(int i = 0; i < G[x].size(); i ++) {
Edge& e = edges[G[x][i]];
int y = e.to;
if(update_dist(d[y], d[x], e))
q.push((HeapNode){d[y], y});
}
}
return d[targ];
}
};
int main() {
int kase = 0;
Dijkstra dijkstra;
while(scanf("%d%d%d%d", &n, &m, &s, &t) != EOF) {
dijkstra.init();
int u, v, a, b, t2;
for(int i = 0; i < m; i ++) {
scanf("%d%d%d%d%d", &u, &v, &a, &b, &t2);
dijkstra.addEdge(u, v, a, b, t2);
}
printf("Case %d: %d\n", ++kase, dijkstra.SP(s, t));
}
return 0;
}