QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#50682 | #1269. New Equipments | ckiseki# | AC ✓ | 26ms | 4416kb | C++ | 3.8kb | 2022-09-28 16:15:30 | 2022-09-28 16:15:32 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using llf = long double;
struct MinCostFlow {
using Cap = int;
using Wei = int64_t;
using PCW = pair<Cap, Wei>;
static constexpr Cap INF_CAP = 1 << 30;
static constexpr Wei INF_WEI = 1LL << 60;
private:
struct Edge {
int to, back;
Cap cap;
Wei wei;
Edge() {}
Edge(int a, int b, Cap c, Wei d) : to(a), back(b), cap(c), wei(d) {}
};
int ori, edd;
vector<vector<Edge>> G;
vector<int> fa, wh;
vector<bool> inq;
vector<Wei> dis;
PCW SPFA() {
fill(inq.begin(), inq.end(), false);
fill(dis.begin(), dis.end(), INF_WEI);
queue<int> qq; qq.push(ori);
dis[ori] = 0;
while (not qq.empty()) {
int u = qq.front(); qq.pop();
inq[u] = false;
for (int i = 0; i < (int)G[u].size(); i++) {
Edge e = G[u][i];
int v = e.to; Wei d = e.wei;
if (e.cap <= 0 || dis[v] <= dis[u] + d)
continue;
dis[v] = dis[u] + d;
fa[v] = u;
wh[v] = i;
if (inq[v]) continue;
qq.push(v);
inq[v] = true;
}
}
if (dis[edd] == INF_WEI)
return { -1, -1 };
Cap mw = INF_CAP;
for (int i = edd; i != ori; i = fa[i])
mw = min(mw, G[fa[i]][wh[i]].cap);
for (int i = edd; i != ori; i = fa[i]) {
auto &eg = G[fa[i]][wh[i]];
eg.cap -= mw;
G[eg.to][eg.back].cap += mw;
}
return { mw, dis[edd] };
}
public:
void init(int n) {
G.clear(); G.resize(n);
fa.resize(n);
wh.resize(n);
inq.resize(n);
dis.resize(n);
}
void add_edge(int st, int ed, Cap c, Wei w) {
G[st].emplace_back(ed, G[ed].size(), c, w);
G[ed].emplace_back(st, G[st].size()-1, 0, -w);
}
PCW solve(int a, int b) {
ori = a, edd = b;
Cap cc = 0;
Wei ww = 0;
vector<int64_t> res{0};
while (true) {
PCW ret = SPFA();
if (ret.first == -1) break;
cc += ret.first;
ww += ret.first * ret.second;
for (int i = 0; i < ret.first; i++) {
res.push_back(res.back() + ret.second);
}
}
for (size_t i = 1; i < res.size(); i++)
cout << res[i] << (i + 1 == res.size() ? '\n' : ' ');
return { cc, ww };
}
} mcmf;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t; cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
map<int,int> mp;
int tot = 0;
const auto getid = [&](int x) -> int {
if (mp.count(x))
return mp[x];
return mp[x] = tot++;
};
vector<tuple<int,int,int64_t>> eds;
for (int i = 0; i < n; i++) {
int64_t a, b, c;
cin >> a >> b >> c;
int x = round(-b / llf(2 * a));
int l = -26 + x;
int r = 26 + x;
if (l < 1) {
l = 1;
r = n;
} else if (r > m) {
l = m - n + 1;
r = m;
}
for (int64_t y = l; y <= r; y++) {
int j = getid(y);
eds.emplace_back(i, j, a*y*y+b*y+c);
}
}
mcmf.init(n + tot + 2);
int S = n + tot, T = S + 1;
for (int i = 0; i < n; i++) {
mcmf.add_edge(S, i, 1, 0);
}
for (auto [x, y, w]: eds) {
mcmf.add_edge(x, y + n, 1, w);
}
for (int i = 0; i < tot; i++) {
mcmf.add_edge(n + i, T, 1, 0);
}
mcmf.solve(S, T);
// cout << mcmf.solve(S, T).second << '\n';
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 3576kb
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: 0
Accepted
time: 26ms
memory: 4416kb
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 ...
output:
2 4 9 14 24 40 72 117 170 239 327 445 592 771 972 1202 1467 1772 2117 2506 2954 3461 4035 4690 5415 6223 7137 8145 9272 10499 11858 13366 15003 16798 18736 20810 23058 25517 28172 31062 34194 37566 41209 45136 49371 53924 58847 64143 69813 75884 4 9 17 25 33 43 57 78 107 146 194 266 356 461 590 744 ...
result:
ok 10 lines