QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#607925 | #9424. Stop the Castle 2 | ucup-team4435# | RE | 1ms | 3596kb | C++20 | 8.5kb | 2024-10-03 17:08:23 | 2024-10-03 17:08:23 |
Judging History
answer
#pragma GCC optimize("Ofast")
#include "bits/stdc++.h"
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;
int Bit(int mask, int b) { return (mask >> b) & 1; }
template<class T>
bool ckmin(T &a, const T &b) {
if (b < a) {
a = b;
return true;
}
return false;
}
template<class T>
bool ckmax(T &a, const T &b) {
if (b > a) {
a = b;
return true;
}
return false;
}
// [l, r)
template<typename T, typename F>
T FindFirstTrue(T l, T r, const F &predicat) {
--l;
while (r - l > 1) {
T mid = l + (r - l) / 2;
if (predicat(mid)) {
r = mid;
} else {
l = mid;
}
}
return r;
}
template<typename T, typename F>
T FindLastFalse(T l, T r, const F &predicat) {
return FindFirstTrue(l, r, predicat) - 1;
}
const ll INF = 2e18;
const int INFi = 1e9;
const int N = 30 + 5;
const int LG = 20;
struct matching {
int n, m;
std::vector<std::vector<int>> g;
std::vector<int> p_left, p_right;
matching(int n = 0, int m = 0) :
n(n), m(m), g(n), p_left(n, -1), p_right(m, -1)
{}
std::pair<int, int> size() const {
return {n, m};
}
void add(int left, int right) {
g[left].push_back(right);
}
std::vector<int> used;
int pairs = 0;
bool khun(int v) {
if (used[v] == pairs + 1)
return false;
used[v] = pairs + 1;
for (auto u : g[v])
if (p_right[u] == -1) {
p_right[u] = v;
p_left[v] = u;
return true;
}
for (auto u : g[v])
if (khun(p_right[u])) {
p_right[u] = v;
p_left[v] = u;
return true;
}
return false;
}
int solve(bool need_to_shuffle = false) {
std::fill(p_left.begin(), p_left.end(), -1);
std::fill(p_right.begin(), p_right.end(), -1);
used.assign(n, 0);
std::vector<int> order(n);
std::iota(order.begin(), order.end(), 0);
if (need_to_shuffle) {
std::shuffle(order.begin(), order.end(), std::mt19937(std::chrono::steady_clock::now().time_since_epoch().count()));
for (auto &v : g)
std::shuffle(v.begin(), v.end(), std::mt19937(std::chrono::steady_clock::now().time_since_epoch().count()));
}
pairs = 0;
for (int v : order)
pairs += khun(v);
return pairs;
}
void dfs(int v) {
if (used[v])
return;
used[v] = 1;
for (auto u : g[v])
if (u != p_left[v])
dfs(p_right[u]);
}
std::pair<std::vector<int>, std::vector<int>> minimum_vertex_covering(bool need_to_shuffle = false) {
int pairs = solve(need_to_shuffle);
used.assign(n, 0);
for (int i = 0; i < n; i++)
if (p_left[i] == -1)
dfs(i);
std::vector<int> left;
std::vector<bool> used_right(m);
for (int i = 0; i < n; i++)
if (!used[i]) {
left.push_back(i);
} else if (p_left[i] != -1) {
for (auto j : g[i])
used_right[j] = true;
}
std::vector<int> right;
for (int i = 0; i < m; i++)
if (used_right[i])
right.push_back(i);
assert(int(left.size() + right.size()) == pairs);
return std::make_pair(left, right);
}
};
void solve() {
int n, m, k; cin >> n >> m >> k;
vpi a(n), b(m);
rep(i, n) cin >> a[i].first >> a[i].second;
rep(i, m) cin >> b[i].first >> b[i].second;
vi xx, yy;
rep(i, n) {
xx.push_back(a[i].first);
yy.push_back(a[i].second);
}
rep(i, m) {
xx.push_back(b[i].first);
yy.push_back(b[i].second);
}
sort(all(xx));
xx.resize(unique(all(xx)) - xx.begin());
sort(all(yy));
yy.resize(unique(all(yy)) - yy.begin());
rep(i, n) {
a[i].first = lower_bound(all(xx), a[i].first) - xx.begin();
a[i].second = lower_bound(all(yy), a[i].second) - yy.begin();
}
rep(i, m) {
b[i].first = lower_bound(all(xx), b[i].first) - xx.begin();
b[i].second = lower_bound(all(yy), b[i].second) - yy.begin();
}
int szx = xx.size();
int szy = yy.size();
vector<vector<ar<int, 3>>> in_row(szx), in_col(szy);
rep(i, n) {
in_row[a[i].first].push_back({a[i].second, 0, i});
in_col[a[i].second].push_back({a[i].first, 0, i});
}
rep(i, m) {
in_row[b[i].first].push_back({b[i].second, 1, i});
in_col[b[i].second].push_back({b[i].first, 1, i});
}
vector<pair<int, int>> to(m, {-1, -1});
int ans = 0;
int L = 0;
int R = 0;
vector<pair<int, int>> edges;
rep(i, szx) {
vector<ar<int, 3>> &cur = in_row[i];
sort(all(cur));
for(int l = 0, r = 0; l < cur.size(); l = r) {
r = l + 1;
if (cur[l][1]) continue;
while (r < cur.size() && cur[r][1]) r++;
if (r == cur.size()) {
continue;
}
if (r == l + 1) {
ans++;
continue;
}
ans++;
int v = L++;
for(int j = l + 1; j < r; ++j) {
to[cur[j][2]].first = v;
}
}
}
rep(i, szy) {
vector<ar<int, 3>> &cur = in_col[i];
sort(all(cur));
for(int l = 0, r = 0; l < cur.size(); l = r) {
r = l + 1;
if (cur[l][1]) continue;
while (r < cur.size() && cur[r][1]) r++;
if (r == cur.size()) {
continue;
}
if (r == l + 1) {
ans++;
continue;
}
ans++;
int v = R++;
for(int j = l + 1; j < r; ++j) {
to[cur[j][2]].second = v;
}
}
}
vector<int> ok(m, 0);
vector<vi> gL(L), gR(R);
matching g(L, R);
map<pair<int, int>, int> edge;
rep(i, m) {
if (to[i].first == -1 && to[i].second == -1) {
continue;
}
if (to[i].first == -1) {
gR[to[i].second].push_back(i);
continue;
}
if (to[i].second == -1) {
gL[to[i].first].push_back(i);
continue;
}
gL[to[i].first].push_back(i);
gR[to[i].second].push_back(i);
g.add(to[i].first, to[i].second);
edge[to[i]] = i;
}
int l = m - k;
int cnt2 = g.solve();
rep(i, L) {
if (g.p_left[i] != -1 && l > 0) {
ans -= 2;
pair<int, int> e = {i, g.p_left[i]};
int ind = edge.at(e);
ok[ind] = 1;
l--;
continue;
}
}
rep(i, L) {
if (g.p_left[i] == -1 && l > 0) {
for(auto &j : gL[i]) {
ans--;
ok[j] = 1;
break;
}
}
}
rep(i, R) {
if (g.p_right[i] == -1 && l > 0) {
for(auto &j : gR[i]) {
ans--;
ok[j] = 1;
break;
}
}
}
rep(i, m) {
if (l > 0 && !ok[i]) {
ok[i] = 1;
l--;
}
}
assert(l == 0);
cout << ans << '\n';
rep(i, m) if (!ok[i]) cout << i + 1 << ' ';
cout << '\n';
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(12) << fixed;
int t = 1;
cin >> t;
rep(i, t) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3596kb
input:
3 8 6 4 1 3 2 1 2 6 4 1 4 7 6 1 6 3 6 6 2 3 3 1 4 3 4 6 5 2 6 4 3 2 1 10 12 10 10 10 11 1 4 1 5 1 3 2 1 1 2 1 2 2 2 3
output:
4 2 3 5 6 2 2 0 2 3
result:
ok ok 3 cases (3 test cases)
Test #2:
score: -100
Runtime Error
input:
1224 11 17 14 7 3 4 2 8 13 3 15 3 4 5 11 10 2 3 3 8 6 7 11 2 3 10 4 1 3 12 1 2 5 11 9 11 6 11 10 8 15 1 5 9 14 4 11 1 6 10 7 7 6 11 4 8 4 1 11 18 3 2 14 8 2 14 13 13 9 12 14 12 5 6 8 1 10 5 8 6 8 9 6 6 7 5 12 11 6 11 13 5 1 10 7 6 14 5 6 15 2 4 11 1 1 6 4 14 14 13 9 9 3 10 12 7 5 8 13 9 14 1 9 8 4 9...