Submission #1309667

#TimeUsernameProblemLanguageResultExecution timeMemory
1309667edoLogičari (COCI21_logicari)C++20
110 / 110
161 ms36044 KiB
#include <bits/stdc++.h>

using namespace std;
using ll   = long long;
using vi   = vector<int>;
using vll  = vector<ll>;
using vvi  = vector<vi>;
using vvll = vector<vll>;
using pii  = pair<int,int>;
using pll  = pair<ll,ll>;
using ui    = unsigned int;
using ull   = unsigned long long;
using pui   = pair<ui,ui>;
using pull  = pair<ull,ull>;
using i128 = __int128_t;

template<typename T>
using vc = std::vector<T>;


#define YES cout << "YES\n"
#define NO  cout << "NO\n"
#define yes cout << "yes\n"
#define no  cout << "no\n"
#define Yes cout << "Yes\n"
#define No  cout << "No\n"

template<typename T> void sc(T &x) { cin >> x; }
template<typename T, typename U> void sc(pair<T,U> &p) { sc(p.first), sc(p.second); }
template<typename T> void sc(vector<T> &v) { for (auto &x : v) sc(x); }
template<typename... A> void sc(A&... a) { (sc(a), ...); }


template<typename T> void _pt(const T &x){cout << x;}
template<typename T, typename U> void _pt(const pair<T,U> &p){_pt(p.first); cout << ' '; _pt(p.second);}
template<typename T> void _pt(const vector<T> &v){bool f=1; for(auto &x:v){if(!f) cout<<' '; _pt(x); f=0;}}
template<typename... A> void pt(const A&... a){(_pt(a), ...);}


template<typename T, typename U> bool umin(T &a, const U &b) { return b < a ? (a = b, true) : false; }
template<typename T, typename U> bool umax(T &a, const U &b) { return b > a ? (a = b, true) : false; }
template<typename T> T maxel(const vector<T>& v){ return *max_element(v.begin(), v.end()); }
template<typename T> T minel(const vector<T>& v){ return *min_element(v.begin(), v.end()); }
template<typename T, int N> T maxel(T (&a)[N]) { return *max_element(a, a + N); }
template<typename T, int N> T minel(T (&a)[N]) { return *min_element(a, a + N); }


template<typename C, typename T> auto lb(C& c, const T& x){ return std::lower_bound(c.begin(), c.end(), x); }
template<typename C, typename T> auto ub(C& c, const T& x){ return std::upper_bound(c.begin(), c.end(), x); }

template<typename T> auto lb(std::set<T>& s, const T& x){ return s.lower_bound(x); }
template<typename T> auto ub(std::set<T>& s, const T& x){ return s.upper_bound(x); }
template<typename T> auto lb(const std::set<T>& s, const T& x){ return s.lower_bound(x); }
template<typename T> auto ub(const std::set<T>& s, const T& x){ return s.upper_bound(x); }

#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define FOR1(n)            for (int i=0; i<(n); ++i)
#define FOR2(i,n)          for (int i=0; i<(n); ++i)
#define FOR3(i,l,r)        for (int i=(l); i<(r); ++i)
#define FOR4(i,l,r,k)      for (int i=(l); i<(r); i+=(k))
#define FOR(...)           GET_MACRO(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define ROF1(n)            for (int i=(n)-1; i>=0; --i)
#define ROF2(i,n)          for (int i=(n)-1; i>=0; --i)
#define ROF3(i,l,r)        for (int i=(r)-1; i>=(l); --i)
#define ROF4(i,l,r,k)      for (int i=(r)-1; i>=(l); i-=(k))
#define ROF(...)           GET_MACRO(__VA_ARGS__, ROF4, ROF3, ROF2, ROF1)(__VA_ARGS__)
#define all(c)   (c).begin(), (c).end()
#define allr(c)  (c).rbegin(), (c).rend()
#define eb       emplace_back
#define mp       make_pair
#define mt       make_tuple
#define fi       first
#define se       second
#define pb       push_back
#define trav(x,a) for (auto &x : (a))
#define sz(a) ((int)(a).size())
#define mem(a,v) memset(a, v, sizeof(a))
#define nl pt("\n")

vvi g;
int Otac, Sin; 

struct DSU {
    int n;
    std::vector<int> parent_or_size;

    DSU() : n(0) {}
    DSU(int n) : n(n), parent_or_size(n, -1) {}

    int leader(int a) {
        return parent_or_size[a] < 0 ? a : parent_or_size[a] = leader(parent_or_size[a]);
    }

    bool same(int a, int b) {
        return leader(a) == leader(b);
    }

    int size(int a) {
        return -parent_or_size[leader(a)];
    }

    int merge(int a, int b) {
        a = leader(a), b = leader(b);
        if (a == b) return 1;
        if (-parent_or_size[a] < -parent_or_size[b]) std::swap(a, b);
        parent_or_size[a] += parent_or_size[b];
        parent_or_size[b] = a;
        return 0;
    }

    std::vector<std::vector<int>> groups() {
        std::vector<int> leader_buf(n), group_size(n);
        for (int i = 0; i < n; i++) {
            leader_buf[i] = leader(i);
            group_size[leader_buf[i]]++;
        }
        std::vector<std::vector<int>> result(n);
        for (int i = 0; i < n; i++) result[i].reserve(group_size[i]);
        for (int i = 0; i < n; i++) result[leader_buf[i]].push_back(i);
        result.erase(
            std::remove_if(result.begin(), result.end(),
                           [](const std::vector<int>& v) { return v.empty(); }),
            result.end());
        return result;
    }
}dsu;

vvi readG(int n, int m) {
    vvi _g(n);
    FOR(m) {
        int _u, _v;
        sc(_u, _v);
        // _u--; _v--;
        if(dsu.merge(_u, _v)) {
            Otac = _u;
            Sin = _v;
            continue;
        }
        _g[_u].pb(_v);
        _g[_v].pb(_u);
    }
    return _g;
}

const int N = 1e5 + 5;
ll dp[N][2][2][2][2];
ll INF = 1e15;

ll solve(int u, int ucol, int pcol, int ot, int sp, int par) {
    ll &memo = dp[u][ucol][pcol][ot][sp];
    if(memo != -1) return memo;

    bool flag = (u == Otac && ucol != ot) || (u == Sin && ucol != sp) || (u == Sin && ot && pcol);
    if(flag) return memo = INF; 
    
    // da li vec gleda u plavi node
    bool chk = pcol || (u == Otac && sp) || (u == Sin && ot);

    vc<pll> opt;

    trav(v, g[u]) {
        if(v != par) {
            ll a0 = solve(v, 0, ucol, ot, sp, u);
            ll a1 = solve(v, 1, ucol, ot, sp, u);
            opt.pb({a0, a1});
        }
    }

    ll cost0 = 0;
    trav(Y, opt) {
        if(Y.fi >= INF) {cost0 = INF; break;}
        cost0 += Y.fi;
        if(cost0 >= INF) {cost0 = INF; break;};
    }

    ll cost1 = INF;
    if(!opt.empty()) {
        ll sumF0 = 0;
        int cntF0 = 0, idInf = -1;
        FOR(sz(opt)) {
            auto [a0, a1] = opt[i];
            if(a0 >= INF) {cntF0++; idInf = i;}
            else {
                sumF0 += a0;
                if(sumF0 >= INF) sumF0 = INF;
            }
        }
        if(cntF0 >= 2) {
            cost1 = INF;
        }
        else if(cntF0 == 1) {
            ll a1 = opt[idInf].se;
            if(a1 < INF && sumF0 < INF) cost1 = sumF0 + a1;
        }
        else {
            ll best = INF;
            trav(Y, opt) {
                if(Y.se < INF) umin(best, Y.se - Y.fi);
            }
            if(best < INF && sumF0 < INF) cost1 = sumF0 + best;
        }
    }

    ll add = chk ? cost0 : cost1;
    if(add >= INF) return memo = INF;
    return memo = (ll)ucol + add;
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int m;
    sc(m);

    dsu = DSU(m + 1);
    
    g = readG(m + 1, m);
    mem(dp, -1);
    ll ans = INF;

    FOR(ot, 2) 
        FOR(sn, 2)
            umin(ans, solve(Otac, ot, 0, ot, sn, -1));

    pt(ans == INF ? -1 : ans); nl;
    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...