问题
分析
dijkstra算法的活用,将消耗的时间按照题目中的规则进行计算
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <utility>
#include <map>
#include <string>
#include <queue>
#include <utility>
using namespace std;
const int maxn=305,Inf=0x3f3f3f3f;
struct Edge{
int from,to,dist,open,close;
Edge(int from,int to,int dist,int open,int close):from(from),to(to),dist(dist),open(open),close(close){}
};
struct Node{
int d,u;
Node(int d=0,int u=0):d(d),u(u) {}
bool operator < (const Node &rhs) const {
return d>rhs.d;
}
};
struct Dijkstra{
int n,m;
vector<Edge> edges;
vector<int> G[maxn];
int done[maxn]; //标记是否是最优
int d[maxn]; //距离
int p[maxn]; //前面的入弧
void init(int n){
this->n=n;
for(int i=0;i<n;++i) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int dist,int open,int close){
edges.push_back(Edge(from,to,dist,open,close));
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s,int t){
memset(done,0,sizeof(done));
for(int i=0;i<n;++i) d[i]=Inf;
d[s]=0;
priority_queue<Node> Q;
Q.push(Node(d[s],s));
while(!Q.empty()){
Node x=Q.top();
Q.pop();
int u=x.u;
if(done[u]) continue; //如果已经是最优,不需要重复松弛操作
done[u]=1;
if(u==t) break;
for(int i=0;i<G[u].size();++i){
Edge &e=edges[G[u][i]];
if(done[e.to]) continue;
int remain=d[u]%(e.open+e.close);
if(remain<=e.open-e.dist && d[e.to]>d[u]+e.dist){
d[e.to]=d[u]+e.dist;
p[e.to]=G[u][i];
Q.push(Node(d[e.to],e.to));
}else if(d[e.to]>d[u]+e.open+e.close-remain+e.dist){
d[e.to]=d[u]+e.open+e.close-remain+e.dist;
p[e.to]=G[u][i];
Q.push(Node(d[e.to],e.to));
}
}
}
}
};
Dijkstra dij;
int n,m,s,t,kase=0,u,v,a,b,ti;
int main(void){
while(scanf("%d%d%d%d",&n,&m,&s,&t)==4){
dij.init(n+1);
for(int i=0;i<m;++i){
scanf("%d%d%d%d%d",&u,&v,&a,&b,&ti);
if(a<ti) continue;
dij.AddEdge(u,v,ti,a,b);
// dij.AddEdge(v,u,ti,a,b);
}
dij.dijkstra(s,t);
printf("Case %d: %d\n",++kase,dij.d[t]);
}
return 0;
}