标签:size mil clu tin string ext int name next
题意:
给定一棵树,树上的点有0,1,2三中情况,0代表该点无色。现在需要你将这棵树割掉一些边,使得割掉每条边分割成的两部分均最多只含有一种颜色的点,即分割后的两部分不能1,2点夹杂(0的点数可以任意),问你最多能有几条这样的割点。
dfs求解出所有点以自己为根的子树 i 中1,2,节点的个数num1,num2,然后根据母树与子树之间的num1,num2值做差,能够得到 i 的另一部分的1,2,节点个数,然后再判断这两部分是否符合条件即可。
#include"stdio.h"
#include"string.h"
#include"algorithm"
using namespace std;
const int N = 20010,M = 1001010;
int head[N],ver[M],Next[M],tot;
int a[N],n;
int num1[N],num2[N];
void add(int x,int y)
{
ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot;
}
void dfs(int x,int far)
{
if(a[x] == 1) num1[x] = 1;
else if(a[x] == 2)num2[x] = 1;
for(int i = head[x]; i; i = Next[i]){
int y = ver[i];
if(y == far) continue;
dfs(y,x);
num1[x] += num1[y];
num2[x] += num2[y];
}
}
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i ++) scanf("%d",&a[i]);
for(int i = 1; i < n; i ++){
int x,y; scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dfs(1,-1);
int ans = 0;
for(int i = 2; i <= n; i ++){
int x = num1[1] - num1[i];
int y = num2[1] - num2[i];
if(num1[i] && num2[i]) continue;
else if(x == 0 || y == 0) ans ++;
}
printf("%d\n",ans);
}
标签:size mil clu tin string ext int name next
原文地址:https://www.cnblogs.com/yrz001030/p/12406150.html