제출 #1225048

#제출 시각아이디문제언어결과실행 시간메모리
1225048wedonttalkanymoreThe Xana coup (BOI21_xanadu)C++20
0 / 100
47 ms21832 KiB
#include <bits/stdc++.h>
using namespace std;

const int inf = 1e9;
int n, a[100005];
vector<int> adj[100005];
int dp[100005][2][2];

void dfs(int u, int par) {
    // 1) Tập các con của u
    vector<int> ch;
    for (int v : adj[u]) {
        if (v == par) continue;
        dfs(v, u);
        ch.push_back(v);
    }

    // 2) f[i][p][t]: đã xử lý i con đầu
    //    p = 0/1: có flip u hay không
    //    t = 0/1: trạng thái target hiện tại (bit cuối) của u
    int m = ch.size();
    vector<array<array<int,2>,2>> f(m+1);
    for (int p = 0; p < 2; p++)
        for (int t = 0; t < 2; t++)
            f[0][p][t] = inf;

    // seed bước cơ sở:
    //  - nếu không flip (p=0): bit u = a[u]
    f[0][0][ a[u]   ] = 0;
    //  - nếu flip    (p=1): bit u = a[u]^1, nhưng chi phí flip cộng +1 sẽ thêm ở cuối
    f[0][1][ a[u]^1 ] = 0;

    // 3) DP kết hợp từng con
    for (int i = 1; i <= m; i++) {
        int v = ch[i-1];
        // reset
        for (int p = 0; p < 2; p++)
            for (int t = 0; t < 2; t++)
                f[i][p][t] = inf;

        // transit
        for (int p = 0; p < 2; p++) {
            for (int t = 0; t < 2; t++) {
                if (f[i-1][p][t] >= inf) continue;
                // gộp cây con v: có thể dùng dp[v][0][*] hoặc dp[v][1][*]
                // dp[v][0][0]/[0][1] áp vào f[*][p][...], 
                // dp[v][1][0]/[1][1] áp vào f[*][p][...] tuỳ flip v với target của con
                // lưu ý: khi “ghép” con, bit target của u sẽ đổi parity nếu số con có flip lẻ
                // nhưng ở đây chúng ta không cần track thêm parity edge, vì dp[...] đã bao gồm logic này
                // nên chỉ cần:
                f[i][p][ t       ] = min(f[i][p][ t       ],
                                        f[i-1][p][t] + dp[v][0][0]);
                f[i][p][ t       ] = min(f[i][p][ t       ],
                                        f[i-1][p][t] + dp[v][1][0]);
                f[i][p][ t^1     ] = min(f[i][p][ t^1     ],
                                        f[i-1][p][t] + dp[v][0][1]);
                f[i][p][ t^1     ] = min(f[i][p][ t^1     ],
                                        f[i-1][p][t] + dp[v][1][1]);
            }
        }
    }

    // 4) Bổ sung chi phí +1 nếu chúng ta có flip tại u (p=1)
    dp[u][0][0] = f[m][0][0];
    dp[u][0][1] = f[m][0][1];
    dp[u][1][0] = f[m][1][0] + 1;
    dp[u][1][1] = f[m][1][1] + 1;
}

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

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

    dfs(1, 0);
    int ans = min(dp[1][0][0], dp[1][1][0]);
    if(ans >= inf) cout << "impossible\n";
    else           cout << 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...
#Verdict Execution timeMemoryGrader output
Fetching results...