测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A32197. 黑白翻转题面描述小杨有一棵包含 n 个节点的树,这棵树上的任意一个节点要么是白色,要么是黑色。小杨认为一棵树是美丽树当且仅当在删除所有白色节点之后,剩余节点仍然组成一棵树。小杨每次操作可以选择一个白色节点将它的颜色变为黑色,他想知道自己最少要执行多少次操作可以使得这棵树变为美丽树。

填空题 困难

题目描述

黑白翻转

题面描述

小杨有一棵包含 n 个节点的树,这棵树上的任意一个节点要么是白色,要么是黑色。小杨认为一棵树是美丽树当且仅当在删除所有白色节点之后,剩余节点仍然组成一棵树。

小杨每次操作可以选择一个白色节点将它的颜色变为黑色,他想知道自己最少要执行多少次操作可以使得这棵树变为美丽树。

输入格式

第一行包含一个正整数 n,代表树的节点数。

第二行包含 n 个非负整数a1,a2 .......,an 其中如果 ai =0,则节点 i 的颜色为白色,否则为黑色。

之后 n-1 行,每行包含两个正整数 xi ,yi 代表存在一条连接节点 xi  和 yi 的边。

输出格式

输出一个整数,代表最少执行的操作次数。

样例1

输入

5

0  1  0  1  0

1  2

1  3

3  4

3  5

输出

2

样例解释

将节点 1 和 3 变为黑色即可使这棵树变为美丽树,此时删除白色节点 5,剩余黑色节点仍然组成一棵树。

数据范围

对于全部数据,保证有 1 <= n <= 100000,1 <= ai  <= 1

参考答案

#include<bits/stdc++.h> using namespace std; const int N = 1e5+10; vector<int> g[N]; int col[N],num[N]; int ans,sum; void calc(int x,int fa) { 8num[x]+=col[x]; for(auto i:g[x]) { if(i!=fa) { calc(i,x); num[x]+=num[i]; } } } void dfs(int x,int fa) { int fl=0; if(num[x]!=sum&&num[x]!=0)fl=1; for(auto i:g[x]) { if(i!=fa) { dfs(i,x); if(num[i]!=0&&num[i]!=num[x]-col[x]) { fl=1; } } } if(fl==1&&col[x]!=1)ans++; } int main() { int n; cin>>n; for(int i=1; i<=n; i++) { cin>>col[i]; sum+=col[i]; } for(int i=1; i<n; i++) { int u,v; cin>>u>>v; g[u].push_back(v); g[v].push_back(u); } calc(1,0); dfs(1,0); cout<<ans<<"\n"; }
上一题 下一题