답안 #503032

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
503032 2022-01-07T03:14:02 Z tabr Flood (IOI07_flood) C++17
100 / 100
190 ms 27544 KB
#include <bits/stdc++.h>
using namespace std;
#ifdef tabr
#include "library/debug.cpp"
#else
#define debug(...)
#endif

struct dsu {
    vector<int> p;
    vector<int> sz;
    int n;

    dsu(int _n) : n(_n) {
        p.resize(n);
        iota(p.begin(), p.end(), 0);
        sz.assign(n, 1);
    }

    inline int get(int x) {
        if (p[x] == x) {
            return x;
        } else {
            return p[x] = get(p[x]);
        }
    }

    inline bool unite(int x, int y) {
        x = get(x);
        y = get(y);
        if (x == y) {
            return false;
        }
        if (sz[x] > sz[y]) {
            swap(x, y);
        }
        p[x] = y;
        sz[y] += sz[x];
        return true;
    }

    inline bool same(int x, int y) {
        return (get(x) == get(y));
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<int> x(n), y(n);
    for (int i = 0; i < n; i++) {
        cin >> x[i] >> y[i];
    }
    dsu uf(4 * n + 1);
    int w;
    cin >> w;
    vector<vector<int>> g(n);
    vector<pair<int, int>> e;
    for (int i = 0; i < w; i++) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].emplace_back(b);
        g[b].emplace_back(a);
        e.emplace_back(a, b);
    }
    vector<int> dx = {0, -1, 0, 1};
    vector<int> dy = {1, 0, -1, 0};
    auto sgn = [&](int i) {
        return (i == 0 ? 0 : i / abs(i));
    };
    for (int i = 0; i < n; i++) {
        for (int dir = 0; dir < 4; dir++) {
            int ok = 0;
            for (int j : g[i]) {
                int cx = x[j] - x[i];
                int cy = y[j] - y[i];
                if (sgn(cx) == dx[dir] && sgn(cy) == dy[dir]) {
                    ok = 1;
                    if (dir % 2 == 0) {
                        uf.unite(4 * i + dir, 4 * j + (3 - dir));
                        uf.unite(4 * i + dir + 1, 4 * j + (2 - dir));
                    } else {
                        uf.unite(4 * i + dir, 4 * j + (dir ^ 1));
                        uf.unite(4 * i + (dir + 1) % 4, 4 * j + (((dir + 1) % 4) ^ 1));
                    }
                    break;
                }
            }
            if (!ok) {
                uf.unite(4 * i + dir, 4 * i + (dir + 1) % 4);
            }
        }
    }
    dsu uf2(n);
    for (int i = 0; i < n; i++) {
        for (int j : g[i]) {
            uf2.unite(i, j);
        }
    }
    vector<vector<int>> f(n);
    for (int i = 0; i < n; i++) {
        f[uf2.get(i)].emplace_back(i);
    }
    for (int i = 0; i < n; i++) {
        if (f[i].empty()) {
            continue;
        }
        int k = f[i][0];
        for (int j : f[i]) {
            if (make_pair(x[k], y[k]) > make_pair(x[j], y[j])) {
                k = j;
            }
        }
        uf.unite(4 * k + 2, 4 * n);
    }
    g = vector<vector<int>>(4 * n + 1);
    for (auto &[a, b] : e) {
        for (int dir = 0; dir < 4; dir++) {
            int cx = x[b] - x[a];
            int cy = y[b] - y[a];
            if (sgn(cx) == dx[dir] && sgn(cy) == dy[dir]) {
                int c = a;
                a = uf.get(4 * c + dir);
                b = uf.get(4 * c + (dir + 1) % 4);
                break;
            }
        }
        g[a].emplace_back(b);
        g[b].emplace_back(a);
    }
    vector<int> d(4 * n + 1, -1);
    queue<int> que;
    int r = uf.get(4 * n);
    d[r] = 0;
    que.emplace(r);
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int to : g[v]) {
            if (d[to] == -1) {
                d[to] = d[v] + 1;
                que.emplace(to);
            }
        }
    }
    vector<int> ans;
    for (int i = 0; i < w; i++) {
        auto [a, b] = e[i];
        debug(a, b, d[a], d[b]);
        if (d[a] == d[b]) {
            ans.emplace_back(i);
        }
    }
    cout << ans.size() << '\n';
    for (int i : ans) {
        cout << i + 1 << '\n';
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 332 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 332 KB Output is correct
2 Correct 1 ms 312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 332 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 332 KB Output is correct
2 Correct 1 ms 416 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 5868 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 63 ms 19736 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 60 ms 21436 KB Output is correct
2 Correct 176 ms 26920 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 165 ms 23452 KB Output is correct
2 Correct 177 ms 27544 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 190 ms 23920 KB Output is correct
2 Correct 107 ms 26880 KB Output is correct