QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#572649 | #9315. Rainbow Bracket Sequence | RUOHUI | WA | 3ms | 19172kb | C++20 | 3.3kb | 2024-09-18 15:49:18 | 2024-09-18 15:49:19 |
Judging History
answer
#include "bits/stdc++.h"
#define int long long
#define ull unsigned long long
#define double long double
#define PII pair<int,int>
#define TIII tuple<int,int,int>
#define LL __int128
#define eps 1e-6
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
constexpr int N = 2e5 + 10, M = 2e6 + 10, mod = 1e9 + 7, inf = 1e18;
int n, m, S, T;
//MCMF最小费用最大流
int h[N], cap[M], ne[M], to[M], cost[M], idx;
int pre[N], last[N];
void add(int a, int b, int c, int d)
{
to[idx] = b, cap[idx] = c, cost[idx] = d, ne[idx] = h[a], h[a] = idx++;
to[idx] = a, cap[idx] = 0, cost[idx] = -d, ne[idx] = h[b], h[b] = idx++;
}
int flow[N], dist[N];
int st[N];
bool spfa()
{
for (int i = 0; i <= n + m + 1; i++)
{
st[i] = 0, flow[i] = inf, dist[i] = inf;
}
queue<int> q;
q.push(S), dist[S] = 0, st[S] = true;
pre[T] = -1;
while (q.size())
{
auto u = q.front();
q.pop();
st[u] = false;
for (int i = h[u]; ~i; i = ne[i])
{
int v = to[i], val = cap[i], distance = cost[i];
if (val && dist[v] > dist[u] + distance)
{
dist[v] = dist[u] + distance;
pre[v] = u, last[v] = i;
flow[v] = min(flow[u], val);
if (!st[v])
{
q.push(v);
st[v] = true;
}
}
}
}
return pre[T] ^ -1;
}
PII MCMF()
{
int maxflow = 0, mincost = 0;
while (spfa())
{
maxflow += flow[T];
mincost += flow[T] * dist[T];
int cur = T;
while (cur ^ S)
{
cap[last[cur]] -= flow[T];
cap[last[cur] ^ 1] += flow[T];
cur = pre[cur];
}
}
return {maxflow, mincost};
}
void clear()
{
idx = 0;
}
void solve()
{
memset(h, -1, sizeof h);
cin >> n >> m;
vector<int> color(2 * n + 1), cnt(m + 1), val(2 * n + 1);
//颜色为i的左括号至少达到cnt[i]个
//将左括号的下界转为右括号的上界
for (int i = 1; i <= m; i++) cin >> cnt[i], cnt[i] *= -1;
n *= 2;
for (int i = 1; i <= n; i++)
{
cin >> color[i], cnt[color[i]]++;
}
for (int i = 1; i <= n; i++) cin >> val[i];
S = 0, T = n + m + 1;
//匹配上一个右括号 相当于减去对应位置上的价值
for (int i = 1; i <= m; i++)
{
//右括号颜色为i的数量最多为cnt[i]个
if (cnt[i] < 0) return cout << "-1\n", void();
add(n + i, T, cnt[i], 0);
}
for (int i = 2; i <= n; i++)
{
//表示选择位置i做为右括号的代价为val[i]
add(i, n + color[i], 1, val[i]);
}
//流量表示前面需要 n / 2个左括号
add(S, 1, n / 2, 0);
for (int i = 1; i <= n - 1; i++)
{
add(i, i + 1, inf, 0);
}
auto [maxflow, mincost] = MCMF();
if (maxflow ^ (n / 2)) return cout << "-1\n", void();
cout << accumulate(val.begin() + 1, val.end(), 0ll) - mincost << endl;
clear();
}
signed main()
{
std::ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int Cases = 1;
cin >> Cases;
while (Cases--)
{
solve();
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 19172kb
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: 3ms
memory: 17580kb
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 343766215 2351080746 3673330360 2201471991 -1 1351561190 2539318868 1093935906 4946124799 -1 4600692243 2231197660 3107528418 4640037833 5142301623 -1 1194080633 6403585429 4247389899 -1 4230243225 4836311506 2615588023 5751395565 6003410525 7529223112 -1 5054275471 1467678317 883992368 1...
result:
wrong answer 1st numbers differ - expected: '-1', found: '5220751523'