Topic
Gives nnn workers andmmm pieces of equipment, the equipment number is1, 2, 3... m 1, 2, 3... m1,2,. 3 . . . M .
For workersiii , he has three parametersai, bi, ci a_i, b_i, c_iai,bi,ci, When the worker is equipped with jjFor j equipment, it costsai ∗ j 2 + bi ∗ j + ci a_i * j ^ 2+ b_i * j + c_iai∗j2+bi∗j+cicost of. Think of
it as kkWhen k workers are equipped with equipment, what is the minimum cost?
To allkkAll cases of k need to be output
analysis
Expense flow
Link each employee with the source point, and take nn near the minimum value of each employee’s quadratic function curven points, connected to the employee, all the points on the quadratic function curve are connected to the meeting point, the line connecting the employee to the quadratic function needs to set the cost, other line costs are0 00 , the flow of all lines is1 11
Output the cost of each spfa process
AC code
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn = 3000;
const ll INF = 0x3f3f3f3f3f3f3f3f;
bool flag;
struct Edge {
ll from, to, cap, flow, cost;
Edge(ll u, ll v, ll c, ll f, ll cc)
: from(u), to(v), cap(c), flow(f), cost(cc) {
}
};
struct MCMF {
ll n, m;
vector<Edge> edges;
vector<ll> G[maxn];
ll inq[maxn]; //是否在队列中
ll d[maxn]; //bellmanford
ll p[maxn]; //上一条弧
ll a[maxn]; //可改进量
void init(ll nn) {
this->n = nn;
for (ll i = 0; i <= n; ++i) G[i].clear();
edges.clear();
}
void addEdge(ll from, ll to, ll cap, ll cost) {
edges.emplace_back(Edge(from, to, cap, 0, cost));
edges.emplace_back(Edge(to, from, 0, 0, -cost));
m = (ll) (edges.size());
G[from].emplace_back(m - 2);
G[to].emplace_back(m - 1);
}
bool spfa(ll s, ll t, ll &flow, ll &cost) {
for (ll i = 1; i <= n; ++i) d[i] = INF;
memset(inq, 0, sizeof(inq));
d[s] = 0;
inq[s] = 1;
p[s] = 0;
queue<ll> q;
a[s] = INF;
q.push(s);
while (!q.empty()) {
ll u = q.front();
q.pop();
inq[u] = 0;
for (ll i = 0; i < (ll) (G[u].size()); ++i) {
Edge &e = edges[G[u][i]];
if (e.cap > e.flow && d[e.to] > d[u] + e.cost) {
d[e.to] = d[u] + e.cost;
p[e.to] = G[u][i];
a[e.to] = min(a[u], e.cap - e.flow);
if (!inq[e.to]) {
q.push(e.to);
inq[e.to] = 1;
}
}
}
}
if (d[t] == INF) return false;
flow += a[t];
cost += (ll) d[t] * (ll) a[t];
cout << (flag ? " " : "") << cost;
flag = true;
for (ll u = t; u != s; u = edges[p[u]].from) {
edges[p[u]].flow += a[t];
edges[p[u] ^ 1].flow -= a[t];
}
return true;
}
ll MincostMaxflow(ll s, ll t, ll &cost) {
ll flow = 0;
cost = 0;
while (spfa(s, t, flow, cost));
return flow;
}
} mcmf;
struct Node {
ll a, b, c;
ll l, r;
ll cal(ll x) {
return a * x * x + b * x + c;
}
void make(ll n, ll m) {
ll mid = -b / 2 / a;
l = mid - n / 2 - 1;
r = mid + n / 2 + 1;
l = max(1ll, l);
r = min(m, r);
if (r == m) {
l = r - n - 2;
} else if (l == 1) {
r = l + n + 2;
}
}
} node[60];
void solve() {
ll T;
cin >> T;
for (ll ts = 0; ts < T; ++ts) {
flag = false;
unordered_map<ll, ll> trans;
ll n, m;
cin >> n >> m;
ll ind = 51;
for (ll i = 1; i <= n; ++i) {
cin >> node[i].a >> node[i].b >> node[i].c;
node[i].make(n, m);
ll l = node[i].l;
ll r = node[i].r;
assert(r - l < 60);
for (ll j = l; j <= r; ++j) {
if (trans.count(j)) continue;
trans.insert({
j, ind++});
}
}
ll source = ind + 10, target = ind + 11;
mcmf.init(target + 10);
#ifdef ACM_LOCAL
cerr << target + 10 << endl;
#endif
for (auto &item : trans)
mcmf.addEdge(item.second, target, 1, 0);
for (ll i = 1; i <= n; ++i) {
mcmf.addEdge(source, i, 1, 0);
for (ll j = node[i].l; j <= node[i].r; ++j) {
mcmf.addEdge(i, trans[j], 1, node[i].cal(j));
}
}
ll cost;
mcmf.MincostMaxflow(source, target, cost);
cout << endl;
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#ifdef ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
signed test_index_for_debug = 1;
char acm_local_for_debug;
while (cin >> acm_local_for_debug) {
if (acm_local_for_debug == '$') exit(0);
cin.putback(acm_local_for_debug);
if (test_index_for_debug > 20) {
throw runtime_error("Check the stdin!!!");
}
auto start_clock_for_debug = clock();
solve();
auto end_clock_for_debug = clock();
cout << "Test " << test_index_for_debug << " successful" << endl;
cerr << "Test " << test_index_for_debug++ << " Run Time: "
<< double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
cout << "--------------------------------------------------" << endl;
}
#else
solve();
#endif
return 0;
}