QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#573163 | #9315. Rainbow Bracket Sequence | Peanut_Tang | WA | 0ms | 3976kb | C++14 | 5.8kb | 2024-09-18 17:34:09 | 2024-09-18 17:34:12 |
Judging History
answer
#include <bits/stdc++.h>
#define ll long long
const ll INFLL = 1e18;
const int N = 1005;
int n, m, c[N], cnt[N], L[N];
struct mcmf {
struct edge {
int to;
ll cap;
ll flow;
ll cost;
int rev;
int mark;
};
std::vector<std::vector<edge>> edges;
std::vector<ll> dis;
std::vector<bool> vis;
ll ret;
mcmf(int n) : edges(n + 1), dis(n + 1), vis(n + 1) {}
void add_edge(int from, int to, ll cap, ll cost, int mark = 0, int mark_rev = 0) {
edges[from].push_back({ to, cap, 0, cost, int(edges[to].size()), mark });
edges[to].push_back({ from, 0, 0, -cost, int(edges[from].size() - 1), mark_rev });
}
bool sp(int s, int t) {
dis.assign(edges.size(), INFLL);
dis[s] = 0;
int n = edges.size();
int f = 1;
while (f) {
f = 0;
for (int i = 0; i < n; ++i) {
for (auto&& [to, cap, flow, cost, rev, mark] : edges[i]) {
if (cap > flow and dis[to] > dis[i] + cost) {
dis[to] = dis[i] + cost;
f = 1;
}
}
}
}
return dis[t] != INFLL;
}
ll dfs(int s, int t, ll cap) {
if (vis[s]) {
return 0;
}
vis[s] = 1;
if (s == t) {
return cap;
}
ll res = 0;
int n = edges[s].size();
for (int i = 0; i < n; ++i) {
auto e = edges[s][i];
if (e.cap > e.flow and dis[e.to] == dis[s] + e.cost) {
ll nw = dfs(e.to, t, std::min(cap - res, e.cap - e.flow));
edges[s][i].flow += nw;
edges[e.to][e.rev].flow -= nw;
res += nw;
ret += nw * e.cost;
if (res == cap) {
return res;
}
}
}
return res;
}
// returns: (flow, cost)
std::pair<ll, ll> run(int s, int t) {
ll res = 0; ret = 0;
while (sp(s, t)) {
vis.assign(edges.size(), 0);
ll curr = dfs(s, t, LLONG_MAX);
res += curr;
}
return { res, ret };
}
};
struct bounded_mcmf {
int n, m, S, T;
mcmf net;
ll sum, pre;
std::vector<ll> fl;
std::vector<ll> init;
std::vector<ll> costs;
bounded_mcmf(int n, int m) : sum(0), pre(0), n(n), m(m), S(0), T(n + 1), net(n + 1), fl(m), init(n + 1), costs(m) {}
// handle negative loop case
void add_edge(int from, int to, ll low, ll high, ll cost, int edge_id = -1) {
if (cost < 0) {
__add_edge(from, to, high, high, cost, -1);
__add_edge(to, from, 0, high - low, -cost, edge_id);
} else {
__add_edge(from, to, low, high, cost, edge_id);
}
if (edge_id != -1) {
costs[edge_id] = cost;
if (cost < 0) {
fl[edge_id] += high; // RealFlow = UpperBound - Flow
} else {
fl[edge_id] += low; // RealFlow = LowerBound + Flow
}
}
}
void __add_edge(int from, int to, ll low, ll high, ll cost, int edge_id = -1) {
net.add_edge(from, to, high - low, cost, edge_id, -1);
init[to] += low, init[from] -= low;
pre += low * cost;
}
void prep(int s, int t) {
for (int i = 1; i <= n; ++i) {
if (init[i] > 0) {
net.add_edge(S, i, init[i], 0, -1, -1);
sum += init[i];
} else if (init[i] < 0) {
net.add_edge(i, T, -init[i], 0, -1, -1);
}
}
net.add_edge(t, s, INFLL, 0, -1, -1);
}
std::pair<ll, ll> run_mcf(int s, int t) { // std::min-cost flow
prep(s, t);
auto [res_flow, res_cost] = net.run(S, T);
res_cost += pre;
printf("%lld %lld %lld\n", sum, res_cost, res_flow);
if (sum != res_flow) {
return {-1, -1};
} else {
// for (int from = 1; from <= n; ++from) { // 这个for循环用来输出方案
// for (auto&& [to, cap, flow, cost, rev, mark] : net.edges[from]) {
// if (mark != -1) {
// if (costs[mark] < 0) {
// fl[mark] -= flow;
// } else {
// fl[mark] += flow;
// }
// }
// }
// }
return {res_flow, res_cost};
}
}
};
void Solve() {
scanf("%d %d", &n, &m);
n += n;
int S = n + n + m + 1, T = S + 1;
bounded_mcmf f(T, 4 * n);
for (int i = 1; i <= m; i++) {
int x;
scanf("%d", &x);
f.add_edge(S, i, x, n / 2, 0);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &c[i]);
}
for (int i = 1; i <= n; i++) {
int x;
scanf("%d", &x);
L[i] = x;
f.add_edge(c[i], i + n, 0, 1, -x);
f.add_edge(i + n, i + n + m, 0, 1, 0);
}
for (int i = 1; i < n; i++) {
f.add_edge(i + n + m, i + 1 + n + m, (i + 1) / 2, i, 0);
}
f.add_edge(n + n + m, T, n / 2, n / 2, 0);
std::fill(cnt + 1, cnt + m + 1, 0);
for (int i = 1; i <= n; i++) {
cnt[c[i]]++;
}
for (int i = 1; i <= m; i++) {
if (cnt[i] < L[i]) {
puts("-1");
return;
}
}
auto res = f.run_mcf(S, T);
if (res.first == -1 && res.second == -1) {
puts("-1");
} else {
printf("%lld\n", -res.second);
}
}
int main() {
int tt;
scanf("%d", &tt);
while (tt--) {
Solve();
}
return 0;
}
详细
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 3976kb
input:
2 3 2 1 2 1 2 2 2 1 2 3 1 4 2 2 1 3 2 2 2 1 2 2 2 1 2 3 1 4 2 2 1
output:
-1 -1
result:
wrong answer 1st numbers differ - expected: '9', found: '-1'