#include<bits/stdc++.h>
using namespace std;
#define int long long
vector<vector<int>> adj;
vector<vector<vector<int>>> dp;
// int INF = numeric_limits<int>::max()/8;
int INF = 2e5;
int r = -1;
vector<bool> ostate;
int determine(priority_queue<int,vector<int>,greater<int>>& delta, int s){
int mi = s;
while(delta.size() >= 2 && delta.top() < 0){
s += delta.top();
delta.pop();
s += delta.top();
delta.pop();
mi = min(mi,s);
}
return mi;
}
void clearpq(priority_queue<int,vector<int>,greater<int>>& pq){
while(pq.size()) pq.pop();
}
void DFS(int v, int p){
// if v is a leaf, then not doing anything will cause the node to be in the same state or flipping it will cause it to go to the other state
// no other dp-state can be reached
if(v != r && adj[v].size() == 1){
dp[v][ostate[v]][0] = 0;
dp[v][!ostate[v]][1] = 1;
return;
}
vector<int> child;
for(auto u : adj[v]){
if(u == p) continue;
DFS(u,v);
child.push_back(u);
}
if(child.size() == 1){
int a = child[0];
dp[v][ostate[v]][0] = dp[a][1][0];
dp[v][!ostate[v]][0] = dp[a][1][1];
dp[v][!ostate[v]][1] = dp[a][0][0]+1;
dp[v][ostate[v]][1] = dp[a][0][1]+1;
}else{
// no change, no ops
int s = 0;
priority_queue<int,vector<int>,greater<int>> delta;
for(auto c : child){
s += dp[c][1][0];
delta.push(dp[c][1][1]-dp[c][1][0]);
}
dp[v][ostate[v]][0] = determine(delta,s);
clearpq(delta); s = 0;
// change, no ops
for(auto c : child){
s += dp[c][1][0];
delta.push(dp[c][1][1]-dp[c][1][0]);
}
s += delta.top(); delta.pop();
dp[v][!ostate[v]][0] = determine(delta,s);
clearpq(delta); s = 0;
// no change, ops
for(auto c : child){
s += dp[c][0][0];
delta.push(dp[c][0][1]-dp[c][0][0]);
}
dp[v][!ostate[v]][1] = determine(delta,s)+1;
clearpq(delta); s = 0;
// change, ops
for(auto c : child){
s += dp[c][0][0];
delta.push(dp[c][0][1]-dp[c][0][0]);
}
s += delta.top(); delta.pop();
dp[v][ostate[v]][1] = determine(delta,s)+1;
clearpq(delta); s = 0;
}
cerr <<"";
}
int32_t main(){
int n;
cin >> n;
adj.resize(n);
dp = vector<vector<vector<int>>>(n, vector<vector<int>>(2, vector<int>(2,INF)));
for(int i = 0; i < n-1LL; i++){
int a,b;
cin >> a >> b;
a--;b--;
adj[a].push_back(b);
adj[b].push_back(a);
}
ostate.resize(n);
for(int i = 0; i < n; i++){
int a;
cin >> a;
ostate[i] = a;
ostate[i] = !ostate[i];
}
for(int i = 0; i < n; i++){
if(adj[i].size() <= 2) {
r = i;
break;
}
}
DFS(r,r);
int ans = min({dp[r][1][0],dp[r][1][1]});
if(ans >= INF){
cout << "impossible\n";
return 0;
}
cout << ans << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |