Submission #1339937

#TimeUsernameProblemLanguageResultExecution timeMemory
1339937domiThe Xana coup (BOI21_xanadu)C++20
100 / 100
47 ms28552 KiB
#include <bits/stdc++.h>

#define int long long
#define fi first
#define se second

#define sz(a) (int)((a).size())
#define all(a) (a).begin(), (a).end()

#define lsb(x) (x & (-x))
#define vi vector<int>
#define YES { cout << "YES" << endl; return; }
#define NO { cout << "NO" << endl; return; }

using ll = long long;
using pii = std::pair<int, int>;

const int NMAX = 1e5;

using namespace std;

vector<int> T[NMAX + 5];
int dp[NMAX + 5][2][2], a[NMAX + 5], mn[NMAX + 5], n;

void dfs(int nod ,int p = -1) {
    vector<int> sons;
    for (auto &son : T[nod]) {
        if (son == p) continue;
        dfs(son, nod);
        sons.push_back(son);
    }

    dp[nod][0][0] = dp[nod][0][1] = dp[nod][1][0] = dp[nod][1][1] = INT_MAX;
    if (sons.empty()) {
        dp[nod][a[nod]][0] = 0;
        dp[nod][(a[nod] ^ 1)][1] = 1;
        return;
    }

    for (int use = 0; use < 2; ++use) {
        ///a[nod] ^ use_son = v
        ///val_son = use

        vector<int> dif;
        int offset = use;
        for (auto &son : sons) {
            offset += dp[son][use][0];
            dif.push_back(dp[son][use][1] - dp[son][use][0]);
        }

        dp[nod][(a[nod] ^ use)][use] = offset;
        sort(all(dif));
        for (int i = 0, v = (a[nod] ^ use); i < sz(dif); ++i) {
            v ^= 1;
            offset += dif[i];
            dp[nod][v][use] = min(dp[nod][v][use], offset);
        }
    }
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    cin >> n;

    for (int i = 0, u, v; i < n - 1; ++i) {
        cin >> u >> v;
        T[u].push_back(v);
        T[v].push_back(u);
    }

    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    dfs(1);
    int ans = min(dp[1][0][1], dp[1][0][0]);

    if (ans == INT_MAX) {
        cout << "impossible\n";
        exit(0);
    }

    cout << ans << '\n';
    return 0;
}
/*
    dp[u][val][used] - numarul minim astfel incat
    tot subarborele lui u este rezolvat pe nodul u se afla valoarea val
    si used reprezinta daca am folosit operatia pe nodul u
*/
#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...