QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#623436#9424. Stop the Castle 2xorzjRE 105ms11336kbC++179.3kb2024-10-09 11:59:192024-10-09 11:59:28

Judging History

This is the latest submission verdict.

  • [2024-10-09 11:59:28]
  • Judged
  • Verdict: RE
  • Time: 105ms
  • Memory: 11336kb
  • [2024-10-09 11:59:19]
  • Submitted

answer

#include <bits/stdc++.h>
#define rep(a, b, c) for (int a = b; a <= c; a++)
#define ALL(x) (x).begin(), (x).end()
#define IOS cin.tie(0)->sync_with_stdio(false)
#ifdef LOCAL
#include "debug.h"
#else
#define deb(...) 42
#endif
#define OPENSTACK
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
const int MAXN = 2e5 + 5;
const int INF = 0x3f3f3f3f;
namespace flow {
    const int N = 2e5 + 5, M = 1e5 + 5;
    struct edge {
        int next, to, w;
    } e[M << 1];
    int n, s, t;
    int head[N], cnt, cur[N], dis[N];
    void init(int n_, int s_, int t_)
    {
        s = s_, t = t_, n = n_, cnt = 0;
        for (int i = 0; i < n; i++) head[i] = -1;
    }
    void add_edge(int u, int v, int w)
    {
        e[cnt] = edge{ head[u], v, w };
        head[u] = cnt;
        cnt++;
        e[cnt] = edge{ head[v], u, 0 };
        head[v] = cnt;
        cnt++;
    }
    bool bfs()
    {
        for (int i = 0; i < n; i++) cur[i] = head[i], dis[i] = -1;
        queue<int> q;
        dis[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = head[x]; ~i; i = e[i].next) {
                if (e[i].w) {
                    int y = e[i].to;
                    if (~dis[y]) continue;
                    dis[y] = dis[x] + 1;
                    q.push(y);
                }
            }
        }
        return ~dis[t];
    }
    int dfs(int x, int flow)
    {
        int ans = 0;
        if (x == t) return flow;
        for (int i = cur[x]; ~i; i = e[i].next, cur[x] = i) {
            int y = e[i].to, newflow = min(e[i].w, flow);
            if (dis[y] != dis[x] + 1 || !e[i].w) continue;
            newflow = dfs(y, newflow);
            e[i].w -= newflow;
            e[i ^ 1].w += newflow;
            flow -= newflow;
            ans += newflow;
            if (!flow) break;
        }
        return ans;
    }
    int dinic()
    {
        int ans = 0;
        while (bfs()) ans += dfs(s, numeric_limits<int>::max());
        return ans;
    }
    //返回S部点集,必须先跑完flow
    vector<bool> minCut()
    {
        vector<bool> c(n);
        for (int i = 0; i < n; i++) {
            c[i] = (dis[i] != -1);
        }
        return c;
    }
    //返回实际流量和上限流量
    struct Edge {
        int from;
        int to;
        int cap;
        int flow;
    };
    vector<Edge> edges()
    {
        vector<Edge> a;
        for (int i = 0; i < cnt; i += 2) {
            Edge x;
            x.from = e[i + 1].to;
            x.to = e[i].to;
            x.cap = e[i].w + e[i + 1].w;
            x.flow = e[i + 1].w;
            a.push_back(x);
        }
        return a;
    }
}  // namespace flow
using flow::add_edge;
using flow::dinic;
using flow::init;

ll seed = chrono::steady_clock::now().time_since_epoch().count();
mt19937_64 rnd(seed);
int Rnd(int l, int r)
{
    return rnd() % (r - l + 1) + l;
}

void solve()
{
    int debug = 0;
    while (true) {
        int n, m, k, V;
        if (debug)n = 10, m = 10, k = 5, V = 9;
        else cin >> n >> m >> k;
        vector<array<int, 2>>c(n);
        vector<array<int, 2>>blk(m);
        vector<int>tx, ty;
        set<pii>S;
        for (int i = 0; i < n; i++) {
            if (debug) {
                int x = Rnd(1, V), y = Rnd(1, V);
                while (S.count({ x,y }))x = Rnd(1, V), y = Rnd(1, V);
                S.insert({ x,y });
                c[i] = { x,y };
            }
            else {
                cin >> c[i][0] >> c[i][1];
            }
            tx.push_back(c[i][0]);
            ty.push_back(c[i][1]);
        }
        for (int i = 0; i < m; i++) {
            if (debug) {
                int x = Rnd(1, V), y = Rnd(1, V);
                while (S.count({ x,y }))x = Rnd(1, V), y = Rnd(1, V);
                S.insert({ x,y });
                blk[i] = { x,y };
            }
            else cin >> blk[i][0] >> blk[i][1];
            tx.push_back(blk[i][0]);
            ty.push_back(blk[i][1]);
        }

        sort(ALL(tx));
        tx.erase(unique(ALL(tx)), tx.end());
        sort(ALL(ty));
        ty.erase(unique(ALL(ty)), ty.end());

        for (auto& [x, y] : c) {
            x = lower_bound(ALL(tx), x) - tx.begin() + 1;
            y = lower_bound(ALL(ty), y) - ty.begin() + 1;
        }
        for (auto& [x, y] : blk) {
            x = lower_bound(ALL(tx), x) - tx.begin() + 1;
            y = lower_bound(ALL(ty), y) - ty.begin() + 1;
        }

        int N = tx.size(), M = ty.size();
        vector<set<int>>posx(N + 1), posy(M + 1);

        for (auto& [x, y] : c) {
            posx[x].insert(y);
            posy[y].insert(x);
        }
        deb(c, blk);

        int ans = 0;
        for (int x = 1; x <= N; x++) {
            int lst = -1;
            for (auto y : posx[x]) {
                if (lst != -1) {
                    ans++;
                }
                lst = y;
            }
        }
        for (int y = 1; y <= M; y++) {
            int lst = -1;
            for (auto x : posy[y]) {
                if (lst != -1) {
                    ans++;
                }
                lst = x;
            }
        }
        deb(ans);
        // cerr << ans << "\n";

        int cntx = 0, cnty = 0;
        map<array<int, 3>, int>idx, idy;
        vector<vector<int>>adj(m + 1);
        vector<pair<array<int, 3>, array<int, 3>>>E(m);

        int s = 0, t = 2 * m + 1;
        init(t + 1, s, t);
        // deb(posy[2]);
        vector<int>ec(m, -1);
        for (int i = 0; i < m; i++) {
            int x = blk[i][0], y = blk[i][1];
            auto itx = posx[x].lower_bound(y);
            if (itx == posx[x].end() || itx == posx[x].begin()) { flow::cnt += 2; continue; }
            auto ity = posy[y].lower_bound(x);
            if (ity == posy[y].end() || ity == posy[y].begin()) { flow::cnt += 2; continue; }
            auto U = array<int, 3>{ *prev(itx), * itx, x };
            auto V = array<int, 3>{ *prev(ity), * ity, y };
            if (idx.emplace(U, cntx + 1).second)cntx++;
            if (idy.emplace(V, cnty + 1).second)cnty++;
            adj[idx[U]].push_back(idy[V]);
            E[i] = { U,V };
            deb(U, V, i, flow::cnt, idx[U], idy[V]);
            ec[i] = flow::cnt;
            add_edge(idx[U], idy[V] + m, 1);
        }

        vector<int>del(m);
        int used = m - k;
        for (int i = 1; i <= cntx; i++)add_edge(s, i, 1);
        for (int i = 1; i <= cnty; i++)add_edge(i + m, t, 1);
        int g = dinic();
        deb(g);
        auto Edge = flow::edges();
        set<array<int, 3>>deledx, deledy;
        // auto Del = [&](int x, int y) {
        //     deled.insert({ x,y });
        // };
        for (int i = 0; i < m; i++) {
            if (ec[i] == -1)continue;
            auto e = Edge[ec[i] / 2];
            deb(e.flow, e.from, e.to);
            if (e.flow == 1) {
                if (used) {
                    used--;
                    ans -= 2;
                    auto [U, V] = E[ec[i] / 2];
                    deb(U, V);
                    del[i] = 1;
                    deledx.insert(U);
                    deledy.insert(V);

                }
            }
        }
        deb(ans, used);
        // cerr << ans << " " << used << "\n";
        if (used) {
            for (int i = 0; i < m; i++) {
                if (del[i] == 1 || used == 0)continue;
                auto [x, y] = blk[i];
                auto itx = posx[x].lower_bound(y);
                bool ok = 1;
                if (!(itx == posx[x].end() || itx == posx[x].begin()) && deledx.count({ *prev(itx),*itx,x }) == 0) {
                    deledx.insert({ *prev(itx),*itx,x });
                    ok = 0;
                    used--;
                    ans--;
                    del[i] = 1;
                }
                auto ity = posy[y].lower_bound(x);
                if (!(ity == posy[y].end() || ity == posy[y].begin()) && deledy.count({ *prev(ity),*ity,y }) == 0) {
                    deledy.insert({ *prev(ity),*ity,y });
                    used--;
                    ans--;
                    del[i] = 1;
                    // assert(ok == 1);
                }
            }
        }
        deb(ans, used);
        // cerr << used << "\n";
        // for (int i = 0; i < m; i++)cerr << del[i] << " \n"[i == m - 1];
        if (used) {
            for (int i = 0; i < m; i++) {
                if (del[i] == 0 && used) {
                    used--;
                    del[i] = 1;
                }
            }
        }
        // assert(count(ALL(del), 0) == k);
        cout << ans << "\n";
        for (int i = 0; i < m; i++)if (del[i] == 0)cout << i + 1 << " ";
        cout << "\n";
        if (!debug)break;
    }
}
int main()
{
#ifdef LOCAL
#ifdef OPENSTACK
    int size = 128 << 20; // 64MB
    char* p = (char*) malloc(size) + size;
#if (defined _WIN64) or (defined __unix)
    __asm__("movq %0, %%rsp\n" ::"r"(p));
#else
    __asm__("movl %0, %%esp\n" ::"r"(p));
#endif
#endif
#endif
    IOS;
    int _ = 1;
    cin >> _;
    while (_--) {
        solve();
    }
#ifdef LOCAL
#ifdef OPENSTACK
    exit(0);
#else
    return 0;
#endif
#endif
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 5692kb

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: 0
Accepted
time: 105ms
memory: 11336kb

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:

ok ok 1224 cases (1224 test cases)

Test #3:

score: -100
Runtime Error

input:

1
86289 95092 40401
911 152
1 270
135 731
347 451
283 224
338 348
166 346
12 385
590 763
939 176
232 405
122 946
397 576
795 823
546 392
33 718
444 598
954 852
185 662
732 539
172 681
386 148
76 495
163 323
711 201
278 363
531 275
66 122
823 983
234 792
102 188
985 423
804 712
419 636
318 331
693 68...

output:


result: