Submission #1298878

#TimeUsernameProblemLanguageResultExecution timeMemory
1298878kenkunkinThe Xana coup (BOI21_xanadu)C++20
0 / 100
106 ms19084 KiB
#include <bits/stdc++.h>
using namespace std;

void Init()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
}

typedef long long ll;
const int MAXN = 200000 + 5;
const ll INF = (ll)9e18;

int n;
vector<int> g[MAXN];
int initState[MAXN]; // 0 = off, 1 = on
ll dp[MAXN][2][2];   // dp[v][parentPress][pressV]
int parentArr[MAXN];

void Input()
{
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        g[i].clear();
        initState[i] = 0;
    }
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    // read states: either a single string "0101..." or n integers
    string token;
    cin >> token;
    if ((int)token.size() == n) {
        for (int i = 1; i <= n; ++i) initState[i] = token[i-1] - '0';
    } else {
        // token is first number
        initState[1] = stoi(token);
        for (int i = 2; i <= n; ++i) cin >> initState[i];
    }
}

void dfs(int v, int p)
{
    parentArr[v] = p;
    for (int to : g[v]) if (to != p) dfs(to, v);

    // for pressV = 0 and pressV = 1 compute tmp_even/tmp_odd
    for (int parentPress = 0; parentPress <= 1; ++parentPress) {
        for (int pressV = 0; pressV <= 1; ++pressV) {
            // compute tmp for this pressV:
            ll even = 0;
            ll odd = INF;
            for (int to : g[v]) {
                if (to == p) continue;
                ll cand_even = min(
                    (even >= INF ? INF : even + dp[to][pressV][0]),
                    (odd  >= INF ? INF : odd  + dp[to][pressV][1])
                );
                ll cand_odd = min(
                    (odd  >= INF ? INF : odd  + dp[to][pressV][0]),
                    (even >= INF ? INF : even + dp[to][pressV][1])
                );
                even = cand_even;
                odd  = cand_odd;
            }
            int toggles = (parentPress + pressV) & 1; // parity ignoring children
            int needParity = initState[v] ^ toggles; // children parity required: s ^ parentPress ^ pressV
            if (needParity == 0) {
                dp[v][parentPress][pressV] = (pressV ? 1LL : 0LL) + even;
            } else {
                dp[v][parentPress][pressV] = (pressV ? 1LL : 0LL) + odd;
            }
            if (dp[v][parentPress][pressV] > INF) dp[v][parentPress][pressV] = INF;
        }
    }
}

void Bai()
{
    // choose root = 1
    dfs(1, 0);
    ll ans = min(dp[1][0][0], dp[1][0][1]);
    if (ans >= INF/2) cout << -1 << '\n';
    else cout << ans << '\n';
}

int main()
{
    Init();
    Input();
    Bai();
    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...
#Verdict Execution timeMemoryGrader output
Fetching results...