Submission #508326

#TimeUsernameProblemLanguageResultExecution timeMemory
508326KoDLogičari (COCI21_logicari)C++17
110 / 110
103 ms15904 KiB
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < n; ++i) using std::vector; using std::array; using std::pair; using std::tuple; template <class F> struct RecLambda : private F { explicit RecLambda(F&& f) : F(std::forward<F>(f)) {} template <class... Args> decltype(auto) operator()(Args&&... args) const { return F::operator()(*this, std::forward<Args>(args)...); } }; constexpr int inf = std::numeric_limits<int>::max() / 4; void setmin(int& x, const int y) { if (x > y) { x = y; } } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); int N; std::cin >> N; vector<vector<int>> graph(N); vector<int> deg(N); for (int i = 0; i < N; ++i) { int a, b; std::cin >> a >> b; a -= 1, b -= 1; graph[a].push_back(b); graph[b].push_back(a); deg[a] += 1, deg[b] += 1; } std::queue<int> que; for (int i = 0; i < N; ++i) { if (deg[i] == 1) { que.push(i); } } vector<vector<int>> child(N); while (!que.empty()) { const int u = que.front(); que.pop(); for (const int v : graph[u]) { if (deg[v] >= 2) { child[v].push_back(u); } deg[v] -= 1; if (deg[v] == 1) { que.push(v); } } } vector<int> cycle; for (int i = 0; i < N; ++i) { if (deg[i] >= 2) { RecLambda([&](auto&& dfs, const int u) -> void { deg[u] = 0; cycle.push_back(u); for (const int v : graph[u]) { if (deg[v] >= 2) { dfs(v); } } })(i); } } vector<array<array<int, 2>, 2>> tree; for (const int r : cycle) { tree.push_back(RecLambda([&](auto&& dfs, const int u) -> array<array<int, 2>, 2> { array<array<int, 2>, 2> dp = {}; rep(i, 2) rep(j, 2) dp[i][j] = inf; dp[0][0] = 0, dp[1][0] = 1; for (const int v : child[u]) { const auto add = dfs(v); array<array<int, 2>, 2> next = {}; rep(i, 2) rep(j, 2) next[i][j] = inf; rep(i, 2) rep(j, 2) rep(k, 2) { if (j and k) continue; setmin(next[i][j or k], dp[i][j] + add[k][!i]); } dp = std::move(next); } return dp; })(r)); } const int n = tree.size(); int ans = inf; rep(x, 2) rep(y, 2) rep(z, 2) rep(w, 2) { if (y and z) continue; if (x and w) continue; array<array<int, 2>, 2> dp = {}; rep(i, 2) rep(j, 2) dp[i][j] = inf; dp[z][x or w] = tree[0][x][y] + tree[1][z][w]; for (int u = 2; u < n; ++u) { array<array<int, 2>, 2> next = {}; rep(i, 2) rep(j, 2) next[i][j] = inf; rep(i, 2) rep(j, 2) rep(k, 2) rep(l, 2) { if (j == k) continue; if (i and l) continue; setmin(next[k][l or i], dp[i][j] + tree[u][k][l]); } dp = std::move(next); } rep(i, 2) rep(j, 2) { if (j == x) continue; if (i + y + z != 1) continue; setmin(ans, dp[i][j]); } } std::cout << (ans == inf ? -1 : ans) << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...