QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#55056 | #1269. New Equipments | YaoBIG | TL | 2ms | 3800kb | C++17 | 4.8kb | 2022-10-12 07:22:11 | 2022-10-12 07:22:13 |
Judging History
answer
#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i <= (n); i++)
#define revrep(i, a, n) for (auto i = n; i >= (a); i++)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a).size()
template<class T> bool chmin(T &a, T b) { if (a > b) { a = b; return 1; } else return 0; }
template<class T> bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } else return 0; }
using namespace std;
template<class A, class B> string to_string(pair<A, B> p);
template<class A> string to_string(A v) {
bool first = 1;
string res = "{";
for (auto x: v) {
if (!first) res += ", ";
first = 0;
res += to_string(x);
}
res += "}";
return res;
}
template<class A, class B> string to_string(pair<A, B> p) {
return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
void debug_out() { cerr << endl; }
template<class H, class... T> void debug_out(H h, T... t) {
cerr << " " << to_string(h);
debug_out(t...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
template<class Cap, class Cost, Cap Cap_MAX = numeric_limits<Cap>::max(), Cost Cost_MAX = numeric_limits<Cost>::max() / 4>
struct SuccessiveShortestPath {
int n;
struct E { int v; Cap a; Cost w; };
vector<E> e;
vector<vi> g;
vector<Cost> h;
SuccessiveShortestPath(int n): n(n), g(n), h(n) {}
void add(int u, int v, Cap c, Cost w) {
g[u].push_back(sz(e)); e.push_back({v, c, w});
g[v].push_back(sz(e)); e.push_back({u, 0, -w});
}
vector<Cost> mincostflow(int src, int sink, Cap mx_flow = Cap_MAX) {
// Run Bellman-Ford first if necessary.
h.assign(n, Cost_MAX);
h[src] = 0;
rep(rd, 1, n) rep(now, 0, n - 1) for (auto i: g[now]) {
auto [v, c, w] = e[i];
if (c > 0) h[v] = min(h[v], h[now] + w);
}
// Bellman-Ford stops here.
Cost cost = 0;
Cap flow = 0;
vector<Cost> res;
while(mx_flow) {
priority_queue<pair<Cost, int> > pq;
vector<Cost> dis(n, Cost_MAX);
dis[src] = 0; pq.emplace(0, src);
vi pre(n, -1), mark(n, 0);
while (sz(pq)) {
auto [d, now] = pq.top(); pq.pop();
// Using mark[] is safer than compare -d and dis[now] when the cost is float type.
if (mark[now]) continue;
mark[now] = 1;
for (auto i: g[now]) {
auto [v, c, w] = e[i];
Cost off = dis[now] + w + h[now] - h[v];
if (c > 0 && dis[v] > off) {
dis[v] = off;
pq.emplace(-dis[v], v);
pre[v] = i;
}
}
}
if (pre[sink] == -1) break;
rep(i, 0, n - 1) if (dis[i] != Cost_MAX) h[i] += dis[i];
Cap aug = mx_flow;
for(int i = pre[sink]; ~i; i = pre[e[i ^ 1].v]) aug = min(aug, e[i].a);
for(int i = pre[sink]; ~i; i = pre[e[i ^ 1].v]) e[i].a -= aug, e[i ^ 1].a += aug;
mx_flow -= aug;
flow += aug;
cost += aug * h[sink];
res.push_back(cost);
}
return res;
}
// Calculate distance on residual graph
Cost cal_dis(int st, int ed) {
priority_queue<pair<Cost, int> > pq;
vector<Cost> dis(n, Cost_MAX);
dis[st] = 0; pq.emplace(0, st);
vi mark(n, 0);
while (sz(pq)) {
auto [d, now] = pq.top(); pq.pop();
if (mark[now]) continue; // again, using mark is safe when C = double.
mark[now] = 1;
for (auto i: g[now]) {
auto [v, c, w] = e[i];
Cost off = dis[now] + w + h[now] - h[v];
if (c > 0 && dis[v] > off) dis[v] = off, pq.emplace(-dis[v], v);
}
}
return dis[ed] + h[ed] - h[st];
}
};
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int cas; cin >> cas; while (cas--) {
int n, m; cin >> n >> m;
vector<ll> as(n), bs(n), cs(n);
rep(i, 0, n - 1) {
cin >> as[i] >> bs[i] >> cs[i];
}
vector<ll> nums;
rep(i, 0, n - 1) {
ll a = as[i], b = bs[i];
ll x0 = -b / (a * 2);
chmin(x0, 1ll * m);
chmax(x0, 1ll);
vector<ll> pos;
rep(j, 0, n + 5) if (x0 - j >= 1) pos.push_back(x0 - j);
rep(j, 0, n + 5) if (x0 + j <= m) pos.push_back(x0 + j);
sort(all(pos), [&](ll i, ll j) { return a * i * i + b * i < a * j * j + b * j; });
pos.erase(unique(all(pos)), pos.end());
if (sz(pos) > n) pos.resize(n);
nums.insert(nums.end(), all(pos));
}
sort(all(nums));
nums.erase(unique(all(nums)), nums.end());
int tot = sz(nums);
int N = n + tot;
int src = N++, sink = N++;
SuccessiveShortestPath<int, ll> mcmf(N);
rep(i, 0, n - 1) mcmf.add(src, i, 1, 0);
rep(i, 0, tot - 1) mcmf.add(i + n, sink, 1, 0);
const ll off = 2e16;
rep(i, 0, n - 1) {
ll a = as[i], b = bs[i], c = cs[i];
rep(j, 0, tot - 1){
ll x = nums[j];
mcmf.add(i, n + j, 1, a * x * x + b * x + c + off);
}
}
auto res = mcmf.mincostflow(src, sink);
rep(i, 0, n - 1) {
ll x = res[i] - off * (i + 1);
printf("%lld%c", x, " \n"[i == n - 1]);
}
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 2ms
memory: 3800kb
input:
1 3 5 2 3 10 2 -3 10 1 -1 4
output:
4 15 37
result:
ok single line: '4 15 37'
Test #2:
score: -100
Time Limit Exceeded
input:
10 50 50 2 -16 79 8 -21 54 8 -1 3 1 -7 47 5 -20 89 1 -2 47 2 -10 26 10 31 28 2 -16 37 6 -16 44 2 -8 100 3 -26 65 3 -6 91 10 -33 56 2 -7 22 2 -12 74 1 -3 7 7 -30 51 1 -4 8 1 -10 62 2 -5 5 1 -3 38 7 -32 57 4 -24 65 1 -8 97 7 -28 71 5 -13 71 2 -14 49 6 -33 100 2 7 69 8 -22 38 5 -23 88 7 20 57 7 -11 83 ...