Submission #1302649

#TimeUsernameProblemLanguageResultExecution timeMemory
1302649mikolaj00The Xana coup (BOI21_xanadu)C++20
100 / 100
60 ms34728 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

ll const INF = 1e9;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vector<vector<int>> g(n+1);
    for (int i = 0; i < n-1; i++)
    {
        int a, b;
        cin >> a >> b;

        g[a].push_back(b);
        g[b].push_back(a);
    }

    vector<bool> on(n+1);
    for (int i = 1; i <= n; i++)
    {
        int on_i;
        cin >> on_i;
        on[i] = on_i;
    }

    // dp[v][a][b] - zakladajac, ze wierzcholek v jest a i zosatal nacisniety jesli b
    vector<vector<vector<ll>>> dp(n+1, vector<vector<ll>>(2, vector<ll>(2)));

    function<void(int, int)> dfs = [&](int u, int p) -> void
    {
        int children = 0;
        for (auto v : g[u])
        {
            if (v == p)
                continue;
            dfs(v, u);
            children++;
        }

        if (!children)
        {
            dp[u][0][0] = 0;
            dp[u][0][1] = INF;
            dp[u][1][0] = INF;
            dp[u][1][1] = 1;
            return;
        }

        vector<pair<bool, bool>> pos = {{false, false}, {false, true}, {true, false}, {true, true}};
        for (auto[a, b] : pos)
        {
            ll res = b;
            int pressed = b;

            for (auto v : g[u])
            {
                if (v == p)
                    continue;
                if (dp[v][on[v] != b][1] < dp[v][on[v] != b][0])
                {
                    res += dp[v][on[v] != b][1];
                    pressed++;
                }
                else
                    res += dp[v][on[v] != b][0];
            }

            if (res < INF && pressed % 2 != a)
            {
                bool all_inf = true;
                for (auto v : g[u])
                {
                    if (v == p)
                        continue;
                    if (dp[v][on[v] != b][0] != INF && dp[v][on[v] != b][1] != INF)
                        all_inf = false;
                }

                if (all_inf)
                    res = INF;

                ll min_dif = INF;
                for (auto v : g[u])
                {
                    if (v == p)
                        continue;
                    min_dif = min(min_dif, abs(dp[v][on[v] != b][1] - dp[v][on[v] != b][0]));
                }
                res += min_dif;
            }

            dp[u][a][b] = min(res, INF);
        }
    };
    dfs(1, 0);

    ll ans = min(dp[1][on[1]][0], dp[1][on[1]][1]);
    if (ans >= INF)
        cout << "impossible";
    else
        cout << ans;
}
#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...