제출 #1323877

#제출 시각아이디문제언어결과실행 시간메모리
1323877maxiedThe Xana coup (BOI21_xanadu)C++20
10 / 100
50 ms31352 KiB
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;

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

	int n;
	cin >> n;
	vector<vector<int>> adj(n);
	for (int i = 0, u,v ; i < n - 1; i++){
		cin >> u >> v;
		u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	vector<int> t(n);
	for (int i = 0; i < n; i++){
		cin >> t[i];
	}
	vector<vector<vector<i64>>> dp(2, vector<vector<i64>>(2, vector<i64>(n, -1)));
	auto dfs = [&](auto &&me, int u, int p) -> void{
		for (int v : adj[u]){
			if (v == p){
				continue;
			}
			me(me, v, u);
		}
		for (int tg = 0; tg < 2; tg++){
			for (int fl = 0; fl < 2; fl++){
				i64 sure0 = 0, sure1 = 0;
				int uneq = t[u] ^ tg ^ fl;
				int count1 = 0;
				vector<pair<i64,i64>> unsure;
				bool ok = true;
				for (int v : adj[u]){
					if (v == p){
						continue;
					}
					bool k0 = dp[fl][0][v] != -1, k1 = dp[fl][1][v] != -1;
					if (!k0 && !k1){
						ok = false;
						break;
					}
					else if (!k0){
						sure1 += dp[fl][1][v];
						count1++;
					}
					else if (!k1){
						sure0 += dp[fl][0][v];
					}
					else{
						unsure.push_back({dp[fl][0][v], dp[fl][1][v]});
					}
				}
				if (!ok){
					dp[tg][fl][u] = -1;
					continue;
				}
				if (unsure.empty()){
					if (count1 % 2 != uneq){
						dp[tg][fl][u] = -1;
					}
					else{
						dp[tg][fl][u] = sure0 + sure1 + fl;
					}
				}
				else{
					i64 sum = 0;
					vector<i64> ch;
					for (auto &[a, b] : unsure){
						sum += a;
						ch.push_back(b - a);
					}
					sort(ch.begin(), ch.end());
					i64 ans = LLONG_MAX;
					int take = 0;
					while (take < uneq){
						sum += ch[take];
						take++;
					}
					ans = min(ans, sum);
					for (int i = uneq; i < unsure.size(); i += 2){
						while (take < i){
							sum += ch[take];
							take++;
						}
						ans = min(ans, sum);
					}
					dp[tg][fl][u] = ans + fl;
				}
			}
		}
	};
	dfs(dfs, 0, 0);
	if (dp[0][0][0] == -1 && dp[0][1][0] == -1){
		cout << "impossible\n";
	}
	else {
		if (dp[0][0][0] == -1){
			dp[0][0][0] = LLONG_MAX;
		}
		if (dp[0][1][0] == -1){
			dp[0][1][0] = LLONG_MAX;
		}
		cout << min(dp[0][0][0], dp[0][1][0]) << '\n';
	}
}
#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...