题目链接
简单的dijkstra,要注意哦,它是单向边。题意是某条路在某时刻打开某分钟,关闭某分钟,通过该条路需要某分钟。然后给你一个起点和终点,问你最短需要多少时间才能从起点到终点。样例解释:比如第一个样例:起点是1,终点是3。从1到2,打开5分钟,关闭6分钟,通过需要3分钟,从0时刻开始计时,到达2需要3分钟。这时在2的时候时刻已经为3,假如立刻通过该条路的话,需要6分钟,从3时刻到9时刻该路都要打开才能走,而该路是打开5分钟,意思就是在第五时刻过后就会关闭,所以如果走的话就会被困在里面,因而不行,要等到下个周期,门开才能走。
#include<bits/stdc++.h>
const int maxm = 5e4+20;
const int maxn = 3e2+20;
const int INF = 0x3f3f3f3f;
using namespace std;
int n,m,s,t,cnt,cas;
int head[maxn],dis[maxn],vis[maxn];
struct node{
int to;
int next;
int open;
int close;
int sum;
int t;
}e[maxm];
void init(){
cnt = 0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
}
void addedge(int u,int v,int op,int cl,int t){
e[cnt].to = v;
e[cnt].sum = op + cl;
e[cnt].open = op;
e[cnt].close = cl;
e[cnt].t = t;
e[cnt].next = head[u];
head[u] = cnt++;
}
void dij(int s){
for(int i = 1; i <= n ; i++){
dis[i] = INF;
}
dis[s] = 0;
int pp,u;
for(int i = 0 ; i < n ; i++){
pp = INF;
for(int j = 1 ; j <= n ; j++){
if(!vis[j] && pp > dis[j]){
pp = dis[j];
u = j;
}
}
if(pp == INF) break;
vis[u] = 1;
for(int j = head[u] ; ~j ; j = e[j].next){
int v = e[j].to;
int lastime = dis[u];
int now = lastime % e[j].sum;
if(now + e[j].t <= e[j].open){
lastime += e[j].t;
}
else{
lastime += e[j].sum - now + e[j].t;
}
dis[v] = min(dis[v],lastime);
}
}
}
int main(){
int cas = 0;
while(~scanf("%d%d%d%d",&n,&m,&s,&t)){
init();
int a,b,c,d,e1;
for(int i = 1 ; i <= m ; i++){
scanf("%d%d%d%d%d",&a,&b,&c,&d,&e1);
if(e1 > c) continue;//如果走过这条路还没有这条路的打开的时间长,那它这条路就是死路,不能走了
addedge(a,b,c,d,e1);
}
dij(s);
printf("Case %d: %d\n",++cas,dis[t]);
}
return 0;
}