template <classT, int N> classSDC { private: int tot = 0, head[N]; structEdge { int next, to; T dis; } edge[N * 3]; inlinevoidadd_edge(int u, int v, const T& w){ edge[++tot].next = head[u], edge[tot].to = v, edge[tot].dis = w, head[u] = tot; } queue<int> q; T dis[N]; int cnt[N]; bool vis[N]; public: voidclear(){ tot = 0, memset(head, 0, sizeof(head)), memset(edge, 0, sizeof(edge)); while (!q.empty()) q.pop(); memset(cnt, 0, sizeof(cnt)), memset(vis, 0, sizeof(vis)); fill(dis, dis + N, -numeric_limits<T>::max() / 2); } SDC() {clear();} T operator[](int idx) const {return dis[idx];}
voidadd_le(int a, int b, const T& c){add_edge(a, b, -c);} // x[a] - x[b] <= c voidadd_ge(int a, int b, const T& c){add_edge(b, a, c);} // x[a] - x[b] >= c voidadd_eq(int a, int b, const T& c){add_le(a, b, c), add_ge(a, b, c);} // x[a] - x[b] == c voidadd_eq(int a, int b){add_edge(a, b, 0), add_edge(b, a, 0);} // x[a] == x[b]
boolsolve(int n){ for (int i = 0; i <= n; i++) add_edge(n + 1, i, 0); dis[n + 1] = 0, vis[n + 1] = true, cnt[n + 1] = 1, q.emplace(n + 1); while (!q.empty()) { int u = q.front(); q.pop(), vis[u] = false; if (++cnt[u] > n + 1) returnfalse; for (int j = head[u]; j != 0; j = edge[j].next) { int v = edge[j].to; T w = edge[j].dis; if (dis[v] < dis[u] + w) { dis[v] = dis[u] + w; if (!vis[v]) q.emplace(v), vis[v] = true; } } } returntrue; } };
template <classT, int N> classSDC { private: int tot = 0, head[N]; structEdge { int next, to; T dis; } edge[N * 3]; inlinevoidadd_edge(int u, int v, const T& w){ edge[++tot].next = head[u], edge[tot].to = v, edge[tot].dis = w, head[u] = tot; } deque<int> q; T dis[N]; int cnt[N]; bool vis[N]; public: voidclear(){ q.clear(); tot = 0, memset(head, 0, sizeof(head)), memset(edge, 0, sizeof(edge)); memset(cnt, 0, sizeof(cnt)), memset(vis, 0, sizeof(vis)); fill(dis, dis + N, -numeric_limits<T>::max() / 2); } SDC() {clear();} T operator[](int idx) const {return dis[idx];}
voidadd_le(int a, int b, const T& c){add_edge(a, b, -c);} // x[a] - x[b] <= c voidadd_ge(int a, int b, const T& c){add_edge(b, a, c);} // x[a] - x[b] >= c voidadd_eq(int a, int b, const T& c){add_le(a, b, c), add_ge(a, b, c);} // x[a] - x[b] == c voidadd_eq(int a, int b){add_edge(a, b, 0), add_edge(b, a, 0);} // x[a] == x[b]
boolsolve(int n){ for (int i = 0; i <= n; i++) add_edge(n + 1, i, 0); dis[n + 1] = 0, vis[n + 1] = true, cnt[n + 1] = 1, q.emplace_back(n + 1); longlong num = 1, sum = 0; while (!q.empty()) { int u = q.front(); while (num * dis[u] < sum) q.pop_front(), q.emplace_back(u), u = q.front(); q.pop_front(), vis[u] = 0, num--, sum -= dis[u]; if (++cnt[u] > n + 1) returnfalse; for (int j = head[u]; j != 0; j = edge[j].next) { int v = edge[j].to; T w = edge[j].dis; if (dis[v] < dis[u] + w) { dis[v] = dis[u] + w; if (vis[v]) continue; vis[v] = 1, num++, sum += dis[v]; if (!q.empty() && dis[v] > dis[q.front()]) q.emplace_front(v); else q.emplace_back(v); } } } returntrue; } };
void _main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> x >> y >> c; sdc.add_le(x, y, c); } if (!sdc.solve(n)) return cout << "NO", void(); for (int i = 1; i <= n; i++) cout << sdc[i] << ' '; }
void _main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> opt >> x >> y; if (opt == 1) cin >> c, sdc.add_ge(x, y, c); if (opt == 2) cin >> c, sdc.add_le(x, y, c); if (opt == 3) sdc.add_eq(x, y); } cout << (sdc.solve(n) ? "Yes" : "No"); }
void _main() { cin >> n >> m; sdc.clear(); // 多测清空 for (int i = 1; i <= m; i++) { cin >> x >> y >> c; sdc.add_eq(y, x - 1, c); } cout << boolalpha << sdc.solve(n) << '\n'; }
void _main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> x >> y >> c; sdc.add_eq(y, x - 1, c); } for (int i = 1; i <= n; i++) sdc.add_ge(i, i - 1, 1); if (!sdc.solve(n)) return cout << -1, void(); cout << sdc[n]; }
void _main(int t) { cin >> n; int m = -1; sdc.clear(); for (int i = 1; i <= n; i++) { cin >> l >> r >> c, m = max(m, r); sdc.add_ge(r + 1, l, c); } for (int i = 1; i <= m + 1; i++) sdc.add_ge(i, i - 1, 0), sdc.add_ge(i - 1, i, -1); sdc.solve(m + 1); cout << sdc[m + 1]; if (t) cout << '\n'; }
void _main() { sdc.clear(), memset(d, 0, sizeof(d)); cin >> n >> k; for (int i = 1; i <= n; i++) cin >> x[i], d[i] = x[i]; sort(d + 1, d + n + 1); int m = unique(d + 1, d + n + 1) - d - 1; for (int i = 1; i <= n; i++) x[i] = lower_bound(d + 1, d + m + 1, x[i]) - d; for (int i = 1; i <= k; i++) { cin >> l >> r >> c; l = lower_bound(d + 1, d + m + 1, l) - d, r = upper_bound(d + 1, d + m + 1, r) - d - 1; sdc.add_ge(r, l - 1, c); } for (int i = 1; i <= n; i++) sdc.add_ge(i, i - 1, 0), sdc.add_ge(i - 1, i, -1); sdc.solve(n); cout << n - sdc[n] << '\n'; }
SDC<int, N> sdc; int n, m, l0, v0, p[N], d[N], pre[N]; structcar { int d, v, a, l, r; intget(int s){return v * v + 2 * a * s;} voidcalc(){ // 分类讨论超速区间起止点 d++; if (a == 0) { // 匀速 if (v > v0) l = d, r = l0; else l = r = -1; } elseif (a > 0) { // 匀加速 if (v > v0) l = d, r = l0; elseif (get(l0 - d) <= v0 * v0) l = r = -1; else l = d + (v0 * v0 - v * v) / (2 * a) + 1, r = l0; } else { // 匀减速 if (v <= v0) l = r = -1; elseif (get(l0 - d) > v0 * v0) l = d, r = l0; else l = d, r = min<int>(l0, ceil(d + 1.0 * (v0 * v0 - v * v) / (2 * a) - 1)); } } } a[N];
void _main() { read(n, m, l0, v0); l0++; for (int i = 1; i <= n; i++) read(a[i].d, a[i].v, a[i].a), a[i].calc(); for (int i = 1; i <= m; i++) read(p[i]), d[i] = ++p[i]; sort(d + 1, d + m + 1); int tot = unique(d + 1, d + m + 1) - d - 1; for (int i = 1; i <= m; i++) p[i] = lower_bound(d + 1, d + tot + 1, p[i]) - d;
for (int i = 1; i <= m; i++) pre[p[i]]++; for (int i = 1; i <= m; i++) pre[i] += pre[i - 1]; int cnt = 0; for (int i = 1; i <= n; i++) { if (a[i].l == -1) continue; a[i].l = lower_bound(d + 1, d + tot + 1, a[i].l) - d; a[i].r = upper_bound(d + 1, d + tot + 1, a[i].r) - d - 1; if (pre[a[i].r] - pre[a[i].l - 1]) cnt++, sdc.add_ge(a[i].r, a[i].l - 1, 1); } for (int i = 1; i <= m; i++) sdc.add_ge(i, i - 1, 0), sdc.add_ge(i - 1, i, -1); sdc.solve(m); cout << cnt << ' ' << m - sdc[m] << '\n';
void _main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> l >> r >> k >> v; l++, r++; if (v == 0) sdc.add_le(r, l - 1, r - l + 1 - k); else sdc.add_ge(r, l - 1, r - l + 1 - (k - 1)); } for (int i = 1; i <= n; i++) sdc.add_ge(i, i - 1, 0), sdc.add_ge(i - 1, i, -1); if (!sdc.solve(n)) return cout << -1, void(); for (int i = 1; i <= n; i++) cout << (sdc[i] > sdc[i - 1]) << ' '; }
inlineboolcheck(int x){ SDC<int, 100> sdc; sdc.add_ge(24, 0, x); for (int i = 1; i <= 24; i++) { sdc.add_ge(i, i - 1, 0), sdc.add_le(i, i - 1, cnt[i]); if (i > 8) sdc.add_ge(i, i - 8, r[i]); else sdc.add_le(i + 16, i, x - r[i]); } return sdc.solve(24) && sdc[24] == x; }
void _main() { for (int i = 1; i <= 24; i++) cin >> r[i]; cin >> n; for (int i = 1; i <= n; i++) cin >> x, cnt[x + 1]++; for (int i = 0; i <= n; i++) { if (check(i)) return cout << i << '\n', void(); } cout << "No Solution\n"; }
SDC<int, N> sdc; int n, m, u, v; int tot = 0, head[N]; structEdge { int next, from, to; } edge[N << 1]; inlinevoidadd_edge(int u, int v){ edge[++tot].next = head[u], edge[tot].from = u, edge[tot].to = v, head[u] = tot; }
bool vis[N]; booldfs(int u){ if (u == n) returntrue; bool can = false; for (int j = head[u]; j != 0; j = edge[j].next) { int v = edge[j].to; if (vis[v]) continue; vis[v] = true; if (dfs(v)) { can = true; sdc.add_ge(v, u, 1), sdc.add_le(v, u, 9); } vis[v] = false; } return can; }
void _main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> u >> v; add_edge(u, v); } if (!dfs(1)) return cout << -1, void(); if (!sdc.solve(n)) return cout << -1, void(); cout << n << ' ' << m << '\n'; for (int i = 1; i <= m; i++) { int u = edge[i].from, v = edge[i].to; cout << u << ' ' << v << ' '; int d = sdc[v] - sdc[u]; if (1 <= d && d <= 9) cout << d << '\n'; else cout << 1 << '\n'; } }
设所求点为 P。当 P 位于 B 左侧时,P 向右运动 d 个单位,到 B,C,D 的距离都会减小,到 a 的距离增加,总和减少 2d。P 位于 C 右侧同理。而 P 位于 B,C 之间时,P 向右运动 d 个单位,到 A,B 的距离增加 d,而到 C,D 的距离减少 d,总和不变且保持最小。由此可得,P 在线段 BC 上(包括端点)时最小。
int n, m, l, r; int dis[N]; deque<int> q; voidbfs(int s){ memset(dis, 0x3f, sizeof(dis)); q.emplace_front(s), dis[s] = 0; while (!q.empty()) { int u = q.front(); q.pop_front(); for (int j = head[u]; j != 0; j = edge[j].next) { int v = edge[j].to, w = edge[j].dis; if (dis[v] > dis[u] + w) { dis[v] = dis[u] + w; (w == 0) ? q.emplace_front(v) : q.emplace_back(v); } } } }
void _main() { cin >> n >> m; for (int i = 1; i <= m; i++) { cin >> l >> r; add_edge(l - 1, r, 0), add_edge(r, l - 1, 0); } for (int i = 1; i <= n; i++) add_edge(i, i - 1, 1), add_edge(i - 1, i, 1); bfs(0); for (int i = 1; i <= n; i++) cout << (dis[i] < dis[i - 1]); }