Codeforces CF1118F1 Tree Cutting (Easy Version) 题解

题目简述

给一棵树,每一个节点都是红色,蓝色或者无色。

一条边是合法的当且仅当删除这一条边之后,树被分成两部分,这两部分不同时含有红色和蓝色。

问有多少条合法的边。

题目分析

考虑先搜索一遍这棵树,并处理出以 x 节点为根的子树中红点和蓝点的数量,记为 redxbluex。树中所有的蓝点和红点的数量记为 BLUERED

如果 uv 这条边是合法的,那么以 v 为根的子树中仅有一种有颜色的点,即以下两种情况:

  • redv=RED 并且 bluev=0
  • bluev=BLUE 并且 redv=0

在搜索的时候判断即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define random(a,b) (rand()%(b-a+1)+a)
const int N=3e5+10;
vector<int> G[N];
int n,a[N],Blue,Red,ans;
pair<int,int> dfs(int u,int father)
{
	int blue=(a[u]==2),red=(a[u]==1);
	for(int v:G[u])
	{
		if(v!=father)
		{
			auto temp=dfs(v,u);
			int A=temp.first,B=temp.second;
			if((A==Blue&&B==0)||(A==0&&B==Red)) ans++;
			blue+=A,red+=B;
		}
	}
	return {blue,red};
}
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    	cin>>a[i];
    	if(a[i]==2) Blue++;
    	if(a[i]==1) Red++;
	}
	for(int u=0,v=0,i=1;i<n;i++)
	{
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	cout<<ans;
	return 0;
}
posted @   zhuluoan  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示