QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#623222#9424. Stop the Castle 2xorzjRE 0ms0kbC++177.6kb2024-10-09 10:43:042024-10-09 10:43:04

Judging History

This is the latest submission verdict.

  • [2024-10-09 10:43:04]
  • Judged
  • Verdict: RE
  • Time: 0ms
  • Memory: 0kb
  • [2024-10-09 10:43:04]
  • 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;

void solve()
{
    int n, m, k;
    cin >> n >> m >> k;

    vector<array<int, 2>>c(n);
    vector<array<int, 2>>blk(m);
    vector<int>tx, ty;

    for (int i = 0; i < n; i++) {
        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++) {
        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);
    }


    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;
        }
    }


    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);

    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())continue;
        auto ity = posy[y].lower_bound(x);
        if (ity == posy[y].end() || ity == posy[y].begin())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 };
        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);
    dinic();
    auto Edge = flow::edges();
    auto Del = [&](int x, int y) {
        posx[x].erase(y);
        posy[y].erase(x);
    };
    for (int i = 0; i < m; i++) {
        if (ec[i] == -1)continue;
        auto e = Edge[ec[i] / 2];
        if (e.flow == 1) {
            if (used) {
                used--;
                ans -= 2;
                auto [U, V] = E[ec[i] / 2];

                del[i] = 1;
                del.push_back(i);

                Del(U[2], U[0]);
                Del(U[2], U[1]);
                Del(V[0], V[2]);
                Del(V[1], V[2]);
            }
        }
    }

    if (used) {
        for (int i = 0; i < m; i++) {
            if (del[i] == 1)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())) {
                Del(x, *prev(itx));
                Del(x, *itx);
                ok = 0;
                used--;
                ans--;
                del[i] = 1;
            }
            auto ity = posy[y].lower_bound(x);
            if (!(ity == posy[y].end() || ity == posy[y].begin())) {
                Del(*prev(ity), y);
                Del(*ity, y);
                used--;
                ans--;
                del[i] = 1;
                assert(ok == 1);
            }
        }
    }
    // 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";
}
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: 0
Runtime Error

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:


result: