题意:在一个赛车比赛中,赛道有n(n <= 300)个交叉点和m(m <= 50000)条单向道路。有趣的是:每条路都是周期性关闭的。每条路用5个整数u,v,a,b,t表示(1<=u,v<=n,1<=a,b,t<=1e5),表示起点是u,重点是v,通过时间为t秒。另外这条路会打开a秒,然后关闭b秒,然后再打开a秒,以此类推。当比赛开始时,每条道路刚刚打开。你的赛车必须在道路打开的时候进入该道路,并且在它关闭之前离开(进出道路不花时间,所以可以在打开的瞬间进入,关闭的瞬间离开)。
从s出发,尽早到达目的地t(1<=s,t<=n)。道路的起点和终点不会相同,但可能有两条道路的起点和终点分别相同。
思路:注意点1.每条道路是单向的
2.有可能某条道路的t > a,这条路根本就不能过
#include
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn = 300 + 2;
int n,m,st,en;
int d[maxn],done[maxn];
vector g[maxn];
struct node
{
int v,dd;
node(int pp,int qq):v(pp),dd(qq){}
bool operator <(const node & rhs) const
{
return dd > rhs.dd;
}
};
struct edge
{
int u,v,a,b,t;
edge(int u1,int v1,int a1,int b1,int t1):u(u1),v(v1),a(a1),b(b1),t(t1){}
};
vector edges;
void init()
{
edges.clear();
for(int i = 0;i < maxn;i++) g[i].clear();
}
void addedge(int a1,int b1,int c1,int d1,int e1)
{
int q;
edges.push_back(edge(a1,b1,c1,d1,e1));
q = edges.size();
g[a1].push_back(q - 1);
}
void dijkstra(int s)
{
priority_queue Q;
for(int i = 0;i < maxn;i++) d[i] = INF;
d[s] = 0; memset(done,0,sizeof(done));
Q.push(node(s,0));
while(!Q.empty())
{
node x = Q.top(); Q.pop();
int u = x.v;
if(done[u]) continue;
done[u] = true;
for(int i = 0;i < g[u].size();i++)
{
edge & e = edges[g[u][i]];
int time = INF,res = d[u] % (e.a + e.b);
if(e.a - res >= e.t) time = e.t;
else if(e.a >= e.t) time = e.a + e.b - res + e.t;
if(d[e.v] > d[u] + time)
{
d[e.v] = d[u] + time;
Q.push(node(e.v,d[e.v]));
}
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int kase = 1;
while(scanf("%d%d%d%d",&n,&m,&st,&en) != EOF)
{
init();
int a1,b1,c1,d1,e1;
for(int i = 1;i <= m;i++)
{
scanf("%d%d%d%d%d",&a1,&b1,&c1,&d1,&e1);
addedge(a1,b1,c1,d1,e1);
}
dijkstra(st);
printf("Case %d: %d\n",kase++,d[en]);
}
return 0;
}