QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#611983 | #9424. Stop the Castle 2 | propane | WA | 2ms | 9692kb | C++20 | 7.1kb | 2024-10-05 00:59:40 | 2024-10-05 00:59:40 |
Judging History
answer
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<array>
#include<set>
#include<limits>
#include<algorithm>
using namespace std;
using LL = long long;
const int maxn = 2e5 + 5, maxm = 2e6 + 5;
template<typename flow_t>
struct MaxFlow{
const flow_t INF = numeric_limits<flow_t>::max() / 2;
int h[maxn], e[maxm], ne[maxm], idx;
flow_t f[maxm];
int cur[maxn], q[maxn], d[maxn];
int V, S, T;
void init(int v, int s, int t){
for(int i = 0; i <= v; i++) h[i] = -1;
idx = 0;
V = v, S = s, T = t;
}
void add(int a, int b, flow_t c, flow_t d = 0){
e[idx] = b, f[idx] = c, ne[idx] = h[a], h[a] = idx++;
e[idx] = a, f[idx] = d, ne[idx] = h[b], h[b] = idx++;
}
bool bfs(){
for(int i = 0; i <= V; i++) d[i] = -1;
int hh = 0, tt = -1;
q[++tt] = S, d[S] = 0, cur[S] = h[S];
while(hh <= tt){
int t = q[hh++];
for(int i = h[t]; ~i; i = ne[i]){
int j = e[i];
if (d[j] == -1 && f[i]){
d[j] = d[t] + 1;
cur[j] = h[j];
if (j == T) return true;
q[++tt] = j;
}
}
}
return false;
}
flow_t find(int u, flow_t limit){
if (u == T) return limit;
flow_t flow = 0;
// start from cur[u] instead of h[u] <- important
for(int i = cur[u]; ~i && flow < limit; i = ne[i]){
int j = e[i];
cur[u] = i;
if (d[j] == d[u] + 1 && f[i]){
flow_t t = find(j, min(f[i], limit - flow));
if (!t) d[j] = -1;
else f[i] -= t, f[i ^ 1] += t, flow += t;
}
}
return flow;
}
flow_t dinic(){
flow_t res = 0, flow;
while(bfs()) while(flow = find(S, INF)) res += flow;
return res;
}
};
MaxFlow<int> flow;
int main(){
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int T;
cin >> T;
while(T--){
int n, m, k;
cin >> n >> m >> k;
k = m - k;
map<int, vector<int> > mp1, mp2;
for(int i = 0; i < n; i++){
int a, b;
cin >> a >> b;
mp1[a].push_back(b);
mp2[b].push_back(a);
}
vector<pair<int, int> > p(m);
for(int i = 0; i < m; i++){
int a, b;
cin >> a >> b;
p[i] = {a, b};
}
auto norm = [&](map<int, vector<int> > &mp){
for(auto &[x, v] : mp){
sort(v.begin(), v.end());
}
};
norm(mp1);
norm(mp2);
auto solve = [&](map<int, vector<int> > &mp1, vector<array<int, 3> > &p){
for(auto &[x, v] : mp1){
for(int i = 0; i + 1 < v.size(); i++){
p.push_back({x, v[i], v[i + 1]});
}
}
};
vector<array<int, 3> > p1, p2;
solve(mp1, p1);
solve(mp2, p2);
const int s1 = p1.size(), s2 = p2.size();
map<int, vector<array<int, 3> > > mp3, mp4;
for(int i = 0; i < s1; i++){
auto [x, y1, y2] = p1[i];
mp3[x].push_back({y1, y2, i});
}
for(int i = 0; i < s2; i++){
auto [y, x1, x2] = p2[i];
mp4[y].push_back({x1, x2, s1 + i});
}
int s = s1 + s2, t = s1 + 1;
flow.init(s1 + s2 + 1, s, t);
for(int i = 0; i < s1; i++) flow.add(s, i, 1);
for(int i = 0; i < s2; i++) flow.add(s1 + i, t, 1);
for(auto [x, y] : p){
if (mp3.contains(x) and mp4.contains(y)){
auto &v1 = mp3[x];
auto it1 = lower_bound(v1.begin(), v1.end(), array{y, 0, 0});
auto &v2 = mp4[y];
auto it2 = lower_bound(v2.begin(), v2.end(), array{x, 0, 0});
if (it1 != v1.begin() and it2 != v2.begin()){
--it1, --it2;
auto [y1, y2, id1] = *it1;
auto [x1, x2, id2] = *it2;
if (y > y1 and y < y2 and x > x1 and x < x2){
flow.add(id1, id2, 1);
}
}
}
}
int ans = s1 + s2;
set<pair<int, int> > st;
for(int x = 0; x < s1; x++){
for(int i = flow.h[x]; ~i and st.size() < k; i = flow.ne[i]){
int j = flow.e[i];
if (j >= s1 and j < s1 + s2 and flow.f[i] == 0){
st.insert({p1[x][0], p2[j - s1][0]});
ans -= 2;
}
}
}
map<int, set<int> > mp5, mp6;
for(auto [x, y] : st){
mp5[x].insert(y);
mp6[y].insert(x);
}
auto check = [&](int x, int y){
if (mp1.contains(x)){
auto check = [&](int x, int y1, int y2){
if (!mp5.contains(x)) return false;
auto &v = mp5[x];
auto it = v.lower_bound(y1);
if (it != v.end() and *it < y2) return true;
return false;
};
auto &v = mp1[x];
auto it = lower_bound(v.begin(), v.end(), y);
if (it != v.begin() and it != v.end()){
int y1 = *prev(it), y2 = *it;
if (y > y1 and y < y2 and !check(x, y1, y2)) return true;
}
}
if (mp2.contains(y)){
auto check = [&](int x, int y1, int y2){
if (!mp6.contains(x)) return false;
auto &v = mp6[x];
auto it = v.upper_bound(y1);
if (it != v.end() and *it < y2) return true;
return false;
};
auto &v = mp2[y];
auto it = lower_bound(v.begin(), v.end(), x);
if (it != v.begin() and it != v.end()){
int x1 = *prev(it), x2 = *it;
if (x > x1 and x < x2 and !check(y, x1, x2)) return true;
}
}
return false;
};
for(auto [x, y] : p){
if (st.size() >= k) break;
if (st.contains({x, y})) continue;
if (check(x, y)){
ans -= 1;
st.insert({x, y});
mp5[x].insert(y);
mp6[y].insert(x);
}
}
for(auto [x, y] : p){
if (st.size() >= k) break;
if (!st.contains({x, y})){
st.insert({x, y});
}
}
cout << ans << '\n';
for(int i = 0; i < m; i++){
if (!st.contains(p[i])){
cout << i + 1 << ' ';
}
}
cout << '\n';
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 2ms
memory: 9692kb
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:
6 3 4 5 6 2 2 0 2 3
result:
wrong answer Participant states the answer to be 6 but is actually 5 (test case 1)