题目链接: http://codeforces.com/group/NVaJtLaLjS/contest/241861/problem/J
题意: 求点1到点n的最短路,给出每条路开通的时间,频率,花费,通过时间,在保证到达的最小时间的尽可能少的花费
思路: 用dijkstra求即可,这道题的坑就在于你需要在路的开通时间前到达路口,否则你需要等待下一次开通,即使你到达的时间刚好开通也需要等待下一轮
#include<bits/stdc++.h>
using namespace std;
const int N=5e2+5;
int n,m;
int tot;
int head[N];
struct node
{
int v,t,c,f,s,nxt;
}edge[N];
int dis[N],cost[N];
void add(int u,int v,int t,int c,int f,int s)
{
edge[tot].v=v;
edge[tot].t=t;
edge[tot].c=c;
edge[tot].s=s;
edge[tot].f=f;
edge[tot].nxt=head[u];
head[u]=tot++;
}
struct nodd
{
int t,co,id;
bool operator < ( const nodd &q)const
{
if(q.t==t)
return co>q.co;
return t>q.t;
}
};
void dijkstra()
{
memset(dis,0x3f,sizeof dis);
memset(cost,0x3f,sizeof cost);
dis[1]=0;
cost[1]=0;
priority_queue<nodd>que;
nodd tmm;
tmm.co=tmm.t=0,tmm.id=1;
que.push(tmm);
while(que.size())
{
nodd tmp;
tmp=que.top();
que.pop();
for(int i=head[tmp.id];i!=-1;i=edge[i].nxt)
{
int t=tmp.t;
int c=tmp.co;
if(t<edge[i].s)
t=edge[i].s;
else{
if ((t-edge[i].s)%edge[i].f!=0)
t=edge[i].s+(t-edge[i].s)/edge[i].f*edge[i].f+edge[i].f;
else t+=edge[i].f;
}
if(t+edge[i].t<dis[edge[i].v])
{
dis[edge[i].v]=t+edge[i].t;
cost[edge[i].v]=c+edge[i].c;
nodd tt;
tt.co=cost[edge[i].v];
tt.id=edge[i].v;
tt.t=dis[edge[i].v];
que.push(tt);
}
else if(t+edge[i].t==dis[edge[i].v]&&c+edge[i].c<cost[edge[i].v])
{
nodd tt;
dis[edge[i].v]=t+edge[i].t;
cost[edge[i].v]=c+edge[i].c;
tt.co=cost[edge[i].v];
tt.id=edge[i].v;
tt.t=dis[edge[i].v];
que.push(tt);
}
}
}
}
int main()
{
cin>>n>>m;
memset(head,-1,sizeof head);
int u,v,t,c,f,s;
for(int i=1;i<=m;i++)
{
cin>>u>>v>>t>>c>>f>>s;
add(u,v,t,c,f,s);
}
dijkstra();
cout<<dis[n]<<' '<<cost[n]<<endl;
return 0;
}