QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#875883 | #10024. Low Cost Set | asdfsdf# | RE | 0ms | 7916kb | C++23 | 7.0kb | 2025-01-30 13:52:06 | 2025-01-30 13:52:07 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pii;
#define MOD 998244353
#define MAX 110
namespace matching {
static const ll INF = 1e18;
static const ll N = 514;
struct edge {
ll u, v, w; edge() {}
edge(ll ui, ll vi, ll wi)
:u(ui), v(vi), w(wi) {
}
};
ll n, n_x;
edge g[N * 2][N * 2];
ll lab[N * 2];
ll match[N * 2], slack[N * 2], st[N * 2], pa[N * 2];
ll flo_from[N * 2][N + 1], S[N * 2], vis[N * 2];
vector<ll> flo[N * 2];
queue<ll> q;
ll e_delta(const edge& e) {
return lab[e.u] + lab[e.v] - g[e.u][e.v].w * 2;
}
void update_slack(ll u, ll x) {
if (!slack[x] || e_delta(g[u][x]) < e_delta(g[slack[x]][x])) {
slack[x] = u;
}
}
void set_slack(ll x) {
slack[x] = 0;
for (ll u = 1; u <= n; ++u)
if (g[u][x].w > 0 && st[u] != x && S[st[u]] == 0)
update_slack(u, x);
}
void q_push(ll x) {
if (x <= n)q.push(x);
else for (size_t i = 0; i < flo[x].size(); i++)
q_push(flo[x][i]);
}
void set_st(ll x, ll b) {
st[x] = b;
if (x > n)for (size_t i = 0; i < flo[x].size(); ++i)
set_st(flo[x][i], b);
}
ll get_pr(ll b, ll xr) {
ll pr = find(flo[b].begin(), flo[b].end(), xr) - flo[b].begin();
if (pr % 2 == 1) {
reverse(flo[b].begin() + 1, flo[b].end());
return (ll)flo[b].size() - pr;
}
else return pr;
}
void set_match(ll u, ll v) {
match[u] = g[u][v].v;
if (u <= n) return;
edge e = g[u][v];
ll xr = flo_from[u][e.u], pr = get_pr(u, xr);
for (ll i = 0; i < pr; ++i) set_match(flo[u][i], flo[u][i ^ 1]);
set_match(xr, v);
rotate(flo[u].begin(), flo[u].begin() + pr, flo[u].end());
}
void augment(ll u, ll v) {
for (;;) {
ll xnv = st[match[u]];
set_match(u, v);
if (!xnv)return;
set_match(xnv, st[pa[xnv]]);
u = st[pa[xnv]], v = xnv;
}
}
ll get_lca(ll u, ll v) {
static ll t = 0;
for (++t; u || v; swap(u, v)) {
if (u == 0)continue;
if (vis[u] == t)return u;
vis[u] = t;
u = st[match[u]];
if (u)u = st[pa[u]];
}
return 0;
}
void add_blossom(ll u, ll lca, ll v) {
ll b = n + 1;
while (b <= n_x && st[b])++b;
if (b > n_x)++n_x;
lab[b] = 0, S[b] = 0;
match[b] = match[lca];
flo[b].clear();
flo[b].push_back(lca);
for (ll x = u, y; x != lca; x = st[pa[y]])
flo[b].push_back(x), flo[b].push_back(y = st[match[x]]), q_push(y);
reverse(flo[b].begin() + 1, flo[b].end());
for (ll x = v, y; x != lca; x = st[pa[y]])
flo[b].push_back(x), flo[b].push_back(y = st[match[x]]), q_push(y);
set_st(b, b);
for (ll x = 1; x <= n_x; ++x)g[b][x].w = g[x][b].w = 0;
for (ll x = 1; x <= n; ++x)flo_from[b][x] = 0;
for (size_t i = 0; i < flo[b].size(); ++i) {
ll xs = flo[b][i];
for (ll x = 1; x <= n_x; ++x)
if (g[b][x].w == 0 || e_delta(g[xs][x]) < e_delta(g[b][x]))
g[b][x] = g[xs][x], g[x][b] = g[x][xs];
for (ll x = 1; x <= n; ++x)
if (flo_from[xs][x]) flo_from[b][x] = xs;
}
set_slack(b);
}
void expand_blossom(ll b) {
for (size_t i = 0; i < flo[b].size(); ++i)
set_st(flo[b][i], flo[b][i]);
ll xr = flo_from[b][g[b][pa[b]].u], pr = get_pr(b, xr);
for (ll i = 0; i < pr; i += 2) {
ll xs = flo[b][i], xns = flo[b][i + 1];
pa[xs] = g[xns][xs].u;
S[xs] = 1, S[xns] = 0;
slack[xs] = 0, set_slack(xns);
q_push(xns);
}
S[xr] = 1, pa[xr] = pa[b];
for (size_t i = pr + 1; i < flo[b].size(); ++i) {
ll xs = flo[b][i];
S[xs] = -1, set_slack(xs);
}
st[b] = 0;
}
bool on_found_edge(const edge& e) {
ll u = st[e.u], v = st[e.v];
if (S[v] == -1) {
pa[v] = e.u, S[v] = 1;
ll nu = st[match[v]];
slack[v] = slack[nu] = 0;
S[nu] = 0, q_push(nu);
}
else if (S[v] == 0) {
ll lca = get_lca(u, v);
if (!lca)return augment(u, v), augment(v, u), true;
else add_blossom(u, lca, v);
}
return false;
}
bool matching() {
memset(S + 1, -1, sizeof(ll) * n_x);
memset(slack + 1, 0, sizeof(ll) * n_x);
q = queue<ll>();
for (ll x = 1; x <= n_x; ++x)
if (st[x] == x && !match[x]) pa[x] = 0, S[x] = 0, q_push(x);
if (q.empty())return false;
for (;;) {
while (q.size()) {
ll u = q.front(); q.pop();
if (S[st[u]] == 1)continue;
for (ll v = 1; v <= n; ++v)
if (g[u][v].w > 0 && st[u] != st[v]) {
if (e_delta(g[u][v]) == 0) {
if (on_found_edge(g[u][v])) return true;
}
else update_slack(u, st[v]);
}
}
ll d = INF;
for (ll b = n + 1; b <= n_x; ++b)
if (st[b] == b && S[b] == 1) d = min(d, lab[b] / 2);
for (ll x = 1; x <= n_x; ++x)
if (st[x] == x && slack[x]) {
if (S[x] == -1) d = min(d, e_delta(g[slack[x]][x]));
else if (S[x] == 0) d = min(d, e_delta(g[slack[x]][x]) / 2);
}
for (ll u = 1; u <= n; ++u) {
if (S[st[u]] == 0) {
if (lab[u] <= d)return 0;
lab[u] -= d;
}
else if (S[st[u]] == 1)lab[u] += d;
}
for (ll b = n + 1; b <= n_x; ++b)
if (st[b] == b) {
if (S[st[b]] == 0) lab[b] += d * 2;
else if (S[st[b]] == 1) lab[b] -= d * 2;
}
q = queue<ll>();
for (ll x = 1; x <= n_x; ++x)
if (st[x] == x && slack[x] && st[slack[x]] != x && e_delta(g[slack[x]][x]) == 0)
if (on_found_edge(g[slack[x]][x])) return true;
for (ll b = n + 1; b <= n_x; ++b)
if (st[b] == b && S[b] == 1 && lab[b] == 0) expand_blossom(b);
}
return false;
}
pair<long long, ll> solve() {
memset(match + 1, 0, sizeof(ll) * n);
n_x = n;
ll n_matches = 0;
long long tot_weight = 0;
for (ll u = 0; u <= n; ++u)st[u] = u, flo[u].clear();
ll w_max = 0;
for (ll u = 1; u <= n; ++u)
for (ll v = 1; v <= n; ++v) {
flo_from[u][v] = (u == v ? u : 0);
w_max = max(w_max, g[u][v].w);
}
for (ll u = 1; u <= n; ++u)lab[u] = w_max;
while (matching())++n_matches;
for (ll u = 1; u <= n; ++u)
if (match[u] && match[u] < u)
tot_weight += g[u][match[u]].w;
return make_pair(tot_weight, n_matches);
}
void add_edge(ll ui, ll vi, ll wi) {
g[ui][vi].w = g[vi][ui].w = wi;
}
void init(ll _n) {
n = _n;
for (ll u = 1; u <= n; ++u)
for (ll v = 1; v <= n; ++v)
g[u][v] = edge(u, v, 0);
}
}
ll L[MAX];
ll R[MAX];
ll A[MAX];
ll S[MAX];
ll mp[MAX][MAX];
signed main() {
ios::sync_with_stdio(false), cin.tie(0);
ll K;
cin >> K;
ll i, j;
for (i = 1; i <= K; i++) cin >> L[i] >> R[i];
for (i = 1; i < K * 2; i++) cin >> A[i];
for (i = K * 2; i >= 1; i--) S[i] = S[i + 1] + A[i];
for (i = 1; i <= K; i++) {
for (j = 1; j <= K; j++) {
if (i == j) continue;
if (L[i] > L[j]) continue;
if (R[i] > R[j] || R[i] < L[j]) mp[i][j] = mp[j][i] = S[L[i]] - S[R[i]] + S[L[j]] - S[R[j]];
else mp[i][j] = mp[j][i] = S[L[i]] - S[R[j]];
}
}
if (K & 1) {
K++;
for (i = 1; i < K; i++) mp[i][K] = mp[K][i] = S[L[i]] - S[R[i]];
}
matching::init(K);
ll INF = 1e12;
for (i = 1; i <= K; i++) for (j = i + 1; j <= K; j++) matching::add_edge(i, j, INF - mp[i][j]);
auto res = matching::solve();
ll mx = INF * K / 2;
cout << mx - res.first;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 5872kb
input:
3 1 4 2 6 3 5 1 2 3 5 8
output:
27
result:
ok answer is '27'
Test #2:
score: 0
Accepted
time: 0ms
memory: 7916kb
input:
5 3 10 1 5 7 8 4 9 2 6 9 9 8 2 4 4 3 5 3
output:
82
result:
ok answer is '82'
Test #3:
score: 0
Accepted
time: 0ms
memory: 5660kb
input:
1 1 2 1
output:
1
result:
ok answer is '1'
Test #4:
score: -100
Runtime Error
input:
91 26 127 13 116 24 76 39 132 29 92 115 164 21 118 32 122 97 108 144 174 53 175 148 168 20 105 2 114 109 128 102 113 81 161 16 100 65 152 142 166 104 169 10 67 61 79 17 145 82 88 63 87 7 171 107 140 34 162 94 157 22 139 41 151 78 120 43 60 55 180 74 170 38 129 18 159 86 106 15 95 9 90 5 101 40 93 25...