1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| #include <cmath> #include <cctype> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <queue>
using namespace std;
struct IOManager { template <typename T> inline bool read(T &x) { char c; bool flag = false; x = 0; while (~ c && ! isdigit(c = getchar()) && c != '-') ; c == '-' && (flag = true, c = getchar()); if (! ~ c) return false; while (isdigit(c)) x = (x << 3) + (x << 1) + c - '0', c = getchar(); return (flag && (x = -x), true); } inline bool read(char &c) { c = '\n'; while (~ c && ! (isprint(c = getchar()) && c != ' ')) ; return ~ c; } inline int read(char s[]) { char c; int len = 0; while (~ c && ! (isprint(c = getchar()) && c != ' ')) ; if (! ~ c) return 0; while (isprint(c) && c != ' ') s[len ++] = c, c = getchar(); return (s[len] = '\0', len); } template <typename T> inline IOManager operator > (T &x) { read(x); return *this; } template <typename T> inline void write(T x) { x < 0 && (putchar('-'), x = -x); x > 9 && (write(x / 10), true); putchar(x % 10 + '0'); } inline void write(char c) { putchar(c); } inline void write(char s[]) { int pos = 0; while (s[pos] != '\0') putchar(s[pos ++]); } template <typename T> inline IOManager operator < (T x) { write(x); return *this; } } io;
struct Junction { bool c; int r, t[2]; };
struct Edge { int v, l, nxt; };
struct Solver { private: static const int N = 310; static const int M = 14010; int s, t, n, m, nume, h[N], dist[N], pre[N]; bool in[N]; Junction junc[N]; Edge e[M << 1]; void add_edge(int u, int v, int l) { e[++ nume] = (Edge) { v, l, h[u] }, h[u] = nume; e[++ nume] = (Edge) { u, l, h[v] }, h[v] = nume; } void input() { io > s > t > n > m; for (int i = 1; i <= n; ++ i) { char c; io > c > junc[i].r > junc[i].t[0] > junc[i].t[1], junc[i].c = c == 'P'; } for (int i = 1; i <= m; ++ i) { int u, v, l; io > u > v > l, add_edge(u, v, l); } } int get(int u, int v, int t) { int cu = junc[u].c, tuu = 0, cv = junc[v].c, tvv = 0; if (t >= junc[u].r) { cu = ! cu; int cnt = (t - junc[u].r) / (junc[u].t[0] + junc[u].t[1]); tuu = junc[u].r + cnt * (junc[u].t[0] + junc[u].t[1]); if (tuu + junc[u].t[cu] <= t) tuu += junc[u].t[cu], cu = ! cu; } if (t >= junc[v].r) { cv = ! cv; int cnt = (t - junc[v].r) / (junc[v].t[0] + junc[v].t[1]); tvv = junc[v].r + cnt * (junc[v].t[0] + junc[v].t[1]); if (tvv + junc[v].t[cv] <= t) tvv += junc[v].t[cv], cv = ! cv; } if (cu == cv) return t; int cnt = 0; while (cu != cv) { if (cnt > 3) return 1e9; if (tuu + (tuu ? junc[u].t[cu] : junc[u].r) < tvv + (tvv ? junc[v].t[cv] : junc[v].r)) tuu += (tuu ? junc[u].t[cu] : junc[u].r), cu = ! cu; else if (tuu + (tuu ? junc[u].t[cu] : junc[u].r) > tvv + (tvv ? junc[v].t[cv] : junc[v].r)) tvv += (tvv ? junc[v].t[cv] : junc[v].r), cv = ! cv; else tuu += (tuu ? junc[u].t[cu] : junc[u].r), cu = ! cu, tvv += (tvv ? junc[v].t[cv] : junc[v].r), cv = ! cv, ++ cnt; } return max(tuu, tvv); } int spfa() { memset(dist, 0x7f, sizeof dist), dist[s] = 0; queue <int> que; que.push(s), in[s] = true; while (! que.empty()) { int u = que.front(); que.pop(), in[u] = false; for (int i = h[u]; i; i = e[i].nxt) { int t = get(u, e[i].v, dist[u]); if (dist[e[i].v] > t + e[i].l) { dist[e[i].v] = t + e[i].l, pre[e[i].v] = u; if (! in[e[i].v]) que.push(e[i].v), in[e[i].v] = true; } } } return dist[t]; } void print(int t) { if (! t) return; print(pre[t]), io < t < ' '; } void process() { int dis = spfa(); io < (dis < 1e9 ? dis : 0) < '\n'; if (dis < 1e9) print(t), io < '\n'; }
public: void solve() { input(), process(); } } solver;
int main() { solver.solve(); return 0; }
|