QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#573130 | #9315. Rainbow Bracket Sequence | Peanut_Tang | WA | 0ms | 3852kb | C++14 | 5.5kb | 2024-09-18 17:28:39 | 2024-09-18 17:28:40 |
Judging History
answer
#include <bits/stdc++.h>
#define ll long long
const ll INFLL = 1e18;
const int N = 1005;
int n, m, c[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);
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);
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: 100
Accepted
time: 0ms
memory: 3792kb
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:
9 -1
result:
ok 2 number(s): "9 -1"
Test #2:
score: -100
Wrong Answer
time: 0ms
memory: 3852kb
input:
50 8 6 0 2 2 0 3 1 3 5 1 1 5 3 5 2 3 2 2 1 2 2 4 6 998133227 879226371 59632864 356493387 62611196 827258251 296576565 204244054 812713672 780267148 614679390 447700005 102067050 544546349 116002772 761999375 1 1 1 1 1 343766215 374461155 3 1 2 1 1 1 1 1 1 796323508 303640854 701432076 853325162 610...
output:
5220751523 374461155 2351080746 3678982693 2201471991 -1 1352480010 2539318868 1093935906 5001074851 -1 4600692243 2231197660 3266162379 4640037833 5740148284 -1 1194080633 6403585429 4469810885 -1 4230243225 4836311506 2615588023 5751395565 6182429100 7606826402 -1 5054275471 1467678317 883992368 1...
result:
wrong answer 1st numbers differ - expected: '-1', found: '5220751523'