题意
给出一些由 \((l,d,k,c,A,B)\) 描述的列车,表示每当时间为 \(l,l+d,l+2d,\cdots,l+(k-1)d\) 时有一半列车从 \(A\) 出发,经过 \(c\) 的时间到达 \(B\)。问如果从站点 \(i,i\in(0,n)\) 出发要去站点 \(n\),最晚什么时候到达站点 \(i\) 可以去到站点 \(n\)。
分析
因为是从所有站点去到站点 \(n\),不难想到反过来 BFS 出从 \(n\) 出发回到各个站点的“最短时间”(因为是反过来所以就是原本的最晚时间)。然后就是朴素的 BFS 了(好像是 SPFA?),这里不再赘述。
代码
#include <bits/stdc++.h>
#define int long long
#define inf 0x7fffffffffffffff
#define N 200005
using namespace std;
int n, m, dis[N];
int head[N], to[N], nxt[N], line[N], tot;
bool vis[N];
struct node {
int l, d, k, c, A, B;
} t[N];
inline int read(int &x) {
char ch = x = 0;
int m = 1;
while (ch < '0' || ch > '9') {
ch = getchar();
if (ch == '-') m *= -1;
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - 48;
ch = getchar();
}
x *= m;
return x;
}
inline void print(int x) {
if (x < 0) putchar('-'), x = -x;
static int stk[50];
int top = 0;
do {
stk[top++] = x % 10;
x /= 10;
} while (x);
while (top) {
putchar(stk[--top] + 48);
}
putchar('\n');
return ;
}
inline void add(int u, int v, int x) {
to[tot] = v;
line[tot] = x;
nxt[tot] = head[u];
head[u] = tot++;
return ;
}
inline void bfs() {
queue<int> q;
q.push(n);
dis[n] = inf; //从 n 出发 BFS
while (!q.empty()) {
int x = q.front();
q.pop();
vis[x] = 0;
for (int i = head[x]; ~i; i = nxt[i]) {
int v = to[i], l = line[i];
if (dis[x] - t[l].c - t[l].l < 0) continue; //已经错过了第一班车,没法往回了
int now = min(t[l].k - 1, (dis[x] - t[l].c - t[l].l) / t[l].d);
now = now * t[l].d + t[l].l; //计算出“最近的”那一班车
if (dis[v] < now) {
dis[v] = now; //更新 dis
if (!vis[v]) vis[v] = 1, q.push(v);
}
}
}
return ;
}
signed main() {
memset(head, -1, sizeof head);
read(n), read(m);
for (int i = 1; i <= n; i++) dis[i] = -inf;
for (int i = 1; i <= m; i++) {
read(t[i].l), read(t[i].d), read(t[i].k), read(t[i].c), read(t[i].A), read(t[i].B);
add(t[i].B, t[i].A, i);
}
bfs();
for (int i = 1; i <= n - 1; i++) {
if (dis[i] == -inf) printf("Unreachable\n"); //无法到达的
else printf("%lld\n", dis[i]);
}
return 0;
}
标签:ch,Last,int,题解,站点,vis,Train,now,dis
From: https://www.cnblogs.com/iloveoi/p/18037756