QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#611964 | #9424. Stop the Castle 2 | propane | WA | 88ms | 12468kb | C++20 | 7.1kb | 2024-10-05 00:44:13 | 2024-10-05 00:44:16 |
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;
ans -= 2 * flow.dinic();
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]});
}
}
}
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';
}
}
詳細信息
Test #1:
score: 100
Accepted
time: 0ms
memory: 9788kb
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
Wrong Answer
time: 88ms
memory: 12468kb
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...
output:
7 3 4 5 6 7 8 9 10 11 12 13 15 16 17 15 2 3 0 3 4 5 6 0 2 3 4 5 6 7 8 9 11 1 3 8 1 2 3 0 1 2 3 4 5 6 7 8 9 10 11 12 1 5 6 7 9 10 11 12 8 17 18 19 1 1 2 3 4 5 6 7 8 7 6 8 10 13 14 15 1 10 11 12 13 14 15 16 17 18 19 20 0 1 1 2 3 0 5 6 7 7 8 12 13 14 15 2 10 11 12 13 14 4 3 4 5 6 7 8 ...
result:
wrong answer Participant states the answer to be 23 but is actually 25 (test case 201)