Submission #482943

#TimeUsernameProblemLanguageResultExecution timeMemory
482943jalsol슈퍼트리 잇기 (IOI20_supertrees)C++17
100 / 100
206 ms23364 KiB
#ifdef LOCAL
#include "local.h"
#else
#include <bits/stdc++.h>
#define debug(...)
#define DB(...)
#endif

using namespace std;

const bool __initialization = []() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cout << setprecision(12) << fixed;
    return true;
}();

using ll = long long;
using ld = long double;

#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()

#define For(i, l, r) for (int i = (l); i <= (r); ++i)
#define Ford(i, r, l) for (int i = (r); i >= (l); --i)
#define Rep(i, n) For (i, 0, (n) - 1)
#define Repd(i, n) Ford (i, (n) - 1, 0)
#define Fe(...) for (auto __VA_ARGS__)

template <class C> inline int isz(const C& c) { return static_cast<int>(c.size()); }
template <class T> inline bool chmin(T& a, const T& b) { return (a > b) ? a = b, true : false; }
template <class T> inline bool chmax(T& a, const T& b) { return (a < b) ? a = b, true : false; }

constexpr ld eps = 1e-9;
constexpr int inf = 1e9;
constexpr ll linf = 1e18;

// =============================================================================

#include "supertrees.h"

constexpr int maxn = 3e5 + 5;

struct UF {
	vector<int> e;
	UF(int n) : e(n, -1) {}
	bool sameSet(int a, int b) { return find(a) == find(b); }
	int size(int x) { return -e[find(x)]; }
	int find(int x) { return e[x] < 0 ? x : e[x] = find(e[x]); }
	bool join(int a, int b) {
		a = find(a), b = find(b);
		if (a == b) return false;
		if (e[a] > e[b]) swap(a, b);
		e[a] += e[b]; e[b] = a;
		return true;
	}
};

int construct(vector<vector<int>> req) {
    int n = req.size();
    vector<vector<int>> ans(n, vector<int>(n));
    UF dsu(n);

    Rep (i, n) {
        For (j, i + 1, n - 1) {
            if (req[i][j] == 3) {
                debug("3");
                return false;
            }
        }
    }

    // forest
    Rep (i, n) {
        For (j, i + 1, n - 1) {
            if (req[i][j] == 1) {
                dsu.join(i, j);
            }
        }
    }

    Rep (i, n) {
        For (j, i + 1, n - 1) {
            if (dsu.sameSet(i, j) != (req[i][j] == 1)) {
                debug("same != req (forest)");
                return false;
            }
        }
    }

    vector<bool> root(n);

    Rep (i, n) {
        int u = dsu.find(i);
        if (u != i) {
            ans[u][i] = ans[i][u] = true;
        }
        else {
            root[i] = true;
        }
    }

    // cycle
    Rep (i, n) {
        For (j, i + 1, n - 1) {
            if (req[i][j] == 2) {
                dsu.join(i, j);
            }
        }
    }

    Rep (i, n) {
        For (j, i + 1, n - 1) {
            if (dsu.sameSet(i, j) != (req[i][j] != 0)) {
                debug("same != req (cycle)");
                return false;
            }
        }
    }

    // combine
    Rep (i, n) {
        if (!root[i]) continue;

        root[i] = false;
        int sz = 1;
        int k = i;

        Rep (j, n) {
            if (root[j] && dsu.sameSet(i, j)) {
                root[j] = false;
                ++sz;
                ans[j][k] = ans[k][j] = true;
                k = j;
            }
        }

        if (sz == 2) {
            debug("cycle size 2");
            return false;
        }

        if (k != i) {
            ans[i][k] = ans[k][i] = true;
        }
    }

    return build(ans), true;
}

// does oj.uz allow IOI-style scoring?
// no
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...