There is a funny car racing in a city with n junctions and m directed roads. The funny part is: each road is open and closed periodically. Each road is associate with two integers (a,b), that means the road will be open for a seconds, then closed for b seconds, then open for a seconds... All these start from the beginning of the race. You must enter a road when it’s open, and leave it before it’s closed again. Your goal is to drive from junction s and arrive at junction t as early as possible. Note that you can wait at a junction even if all its adjacent roads are closed.
Input
There will be at most 30 test cases. The first line of each case contains four integers n, m, s, t (1 ≤ n ≤ 300, 1 ≤ m ≤ 50,000, 1 ≤ s,t ≤ n). Each of the next m lines contains five integers u, v, a, b, t (1 ≤ u,v ≤ n, 1 ≤ a,b,t ≤ 105), that means there is a road starting from junction u ending with junction v. It’s open for a seconds, then closed for b seconds (and so on). The time needed to pass this road, by your car, is t. No road connects the same junction, but a pair of junctions could be connected by more than one road.
Output
For each test case, print the shortest time, in seconds. It’s always possible to arrive at t from s.
Sample Input
3 2 1 3 1 2 5 6 3 2 3 7 7 6 3 2 1 3 1 2 5 6 3 2 3 9 5 6
Sample Output
Case 1: 20 Case 2: 9
Input
There will be at most 30 test cases. The first line of each case contains four integers n, m, s, t (1 ≤ n ≤ 300, 1 ≤ m ≤ 50,000, 1 ≤ s,t ≤ n). Each of the next m lines contains five integers u, v, a, b, t (1 ≤ u,v ≤ n, 1 ≤ a,b,t ≤ 105), that means there is a road starting from junction u ending with junction v. It’s open for a seconds, then closed for b seconds (and so on). The time needed to pass this road, by your car, is t. No road connects the same junction, but a pair of junctions could be connected by more than one road.
Output
For each test case, print the shortest time, in seconds. It’s always possible to arrive at t from s.
Sample Input
3 2 1 3 1 2 5 6 3 2 3 7 7 6 3 2 1 3 1 2 5 6 3 2 3 9 5 6
Sample Output
Case 1: 20 Case 2: 9
思路:用Dijkstra更新维护,每次找出最小的走。
学长的AC代码:
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<queue>
#include<math.h>
#define inf 0x3f3f3f3f
using namespace std;
const int N=303;
const int M=5e4+10;
int m,n,st,en,tot,head[N],dis[N];
bool vis[N];
struct node
{
int v,dis,a,b,net;
} e[M];
void add(int aa,int bb,int cc,int dd,int ee)
{
e[tot].v=bb;
e[tot].dis=cc;
e[tot].a=dd;
e[tot].b=ee;
e[tot].net=head[aa];
head[aa]=tot++;
}
int dij()
{
int time=0;
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[st]=0;
for(int i=1; i<=n; i++)
{
int u=-1,tmp=inf;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]<tmp)
{
tmp=dis[j];
u=j;
}
}
if(u==-1) break;
vis[u]=true;
for(int j=head[u]; j!=-1; j=e[j].net)
{
int aa=e[j].a,bb=e[j].b,dist=e[j].dis;
int t=dis[u]%(aa+bb);
int v=e[j].v;
if(aa<dist) co ntinue;
if(aa-t>=dist&&dis[v]>dis[u]+dist)
{
dis[v]=dis[u]+dist;
time+=dist;
}
else if(aa-t<dist&&dis[v]>dis[u]+dist+aa-t+bb)
{
dis[v]=dis[u]+dist+aa-t+bb;
}
}
}
return dis[en];
}
int main()
{
int u,v,dis,aa,bb,k=1;
while(~scanf("%d%d%d%d",&n,&m,&st,&en))
{
tot=0;
memset(head,-1,sizeof(head));
for(int i=0; i<m; i++)
{
scanf("%d%d%d%d%d",&u,&v,&aa,&bb,&dis);
add(u,v,dis,aa,bb);
}
printf("Case %d: %d\n",k++,dij());
}
}
我的wa代码:和上面代码一样思路。就是找不出错在哪!测试数据:
https://blog.csdn.net/hurmishine/article/details/52318488
#include<algorithm>
#include<stdio.h>
#include<string.h>
#define M 50010
#define inf 0x3f3f3f
using namespace std;
int a[M][10];
int first[310],nextt[M];
int n,m;
int dis[310],vis[310];
int x,y,cas=1;
int dijskl(int x)
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[x]=0;
int k,pan,flag,p,xian,an;
for(int i=0; i<=n; i++)
{
pan=inf,k=-1;
for(int j=0; j<=n; j++)
{
if(!vis[j]&&dis[j]<pan)
{
pan=dis[j];
k=j;
}
}
if(k==-1)
break;
vis[k]=1;
p=first[k];
while(p!=-1)
{
if(a[p][5]>a[p][3])
{
p=nextt[p];
continue;
}
xian=dis[a[p][1]]%(a[p][3]+a[p][4]);
if(a[p][3]-xian>=a[p][5])
{
an=a[p][5];
}
else
{
an=a[p][3]-xian+a[p][4]+a[p][5];
}
if(dis[a[p][2]]>dis[a[p][1]]+an)
{
dis[a[p][2]]=dis[a[p][1]]+an;
}
// if(a[p][3]-xian>=a[p][5]&&dis[a[p][2]]>dis[a[p][1]]+a[p][5])
// {
// dis[a[p][2]]=dis[a[p][1]]+a[p][5];
// }
// else if(a[p][3]-xian<a[p][5]&&dis[a[p][2]]>dis[a[p][1]]+a[p][5]+a[p][3]-xian+a[p][4])
// {
// dis[a[p][2]]=dis[a[p][1]]+a[p][5]+a[p][3]-xian+a[p][4];
// }
p=nextt[p];
}
}
return dis[y];
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&x,&y))
{
memset(first,-1,sizeof(first));
for(int i=1; i<=m; i++)
{
scanf("%d%d%d%d%d",&a[i][1],&a[i][2],&a[i][3],&a[i][4],&a[i][5]);
nextt[i]=first[a[i][1]];
first[a[i][1]]=i;
}
// dijskl(x);
printf("Case %d: %d\n",cas++,dijskl(x));
}
return 0;
}