首页 > 其他分享 >[43] (CSP 集训) CSP-S 模拟 10

[43] (CSP 集训) CSP-S 模拟 10

时间:2024-10-08 12:22:43浏览次数:1  
标签:10 子树内 int 43 CSP 发送 树根 节点

B.清扫

考虑从叶子节点往上推

首先可以发现的几个性质

  • 子树内需要消除的数,要么通过子树根节点 “发送” 到上面(只经过子树内一个叶节点),要么通过自己的叶节点解决
  • 对于子树内既不是根也不是叶节点的节点,节点上的值只能由这一支路的叶节点消除,所以如果他节点上的值和下面节点 “发送” 上来的值不相等时,无解

然后考虑怎么去计算子树根节点向上的 “发送” 数量

设这个数量为 \(k\),子树各支路 “发送” 到子树根节点的数量总和为 \(s\),子树根节点的权值为 \(a\),可以发现

  • 子树内解决会为 \(s\) 带来 \(-2\) 的贡献
  • “发送” 出去会为 \(s\) 带来 \(-1\) 的贡献
  • 无论何种操作,每次操作总会给 \(a\) 带来 \(-1\) 的贡献

因此:

\[k+2(a-k)=s \]

由此可以唯一确定 \(k\),将这个值继续往上传即可

例图

这是一个 \(k=0\) 的图

需要注意的

  • 由题有 \(0\le k\le a\),否则无解
  • 我们在上述式子中只判断了数量关系,但实际上,由于子树内必须要选择不同的叶子配对,因此可能会出现有叶子无法使用的情况,此时是无解的

这种情况的判断方式:\(s\) 个数的最大配对次数是 \(s/2\),其次,每个点不能和自己匹配,所以有一个限制是 \(s-\max\)(其中 \(\max\) 是子树传入的最大值),这两个值取 \(\min\),然后和子树的值总和比较,小于说明有剩余,报告无解

  • 注意 \(n=2\) 的情况需要特判
#include<bits/stdc++.h>
using namespace std;
int n;
int a[100001];
vector<int>e[100001];
int degree[100001];
bool flag=false;
int dfs(int now,int last){
//	cout<<"dfs "<<now<<" "<<last<<endl;
	int res=0,cnt=0,maxn=0;
	for(int i:e[now]){
		if(i!=last){
			cnt++;
			int r=dfs(i,now);
			res+=r;maxn=max(maxn,r);
			if(flag) return 0;
		}
	}
	if(cnt==0){
		return a[now];
	}
	if(cnt==1){
		if(res!=a[now]){
			flag=true;
			return 0;
		}
		return res;
	}
	if(res<a[now] or res>2*a[now]){
		flag=true;
		return 0;
	}
	if(min(res/2,res-maxn)<res-a[now]){
		flag=true;
		return 0;
	} 
	return 2*a[now]-res;
}
int main(){
	freopen("tree.in","r",stdin);
	freopen("tree.out","w",stdout);
//	freopen("b.in","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
	}
	if(n==2){
		cout<<(a[1]==a[2]?"YES":"NO")<<'\n';
		return 0;
	}
	for(int i=1;i<=n-1;++i){
		int x,y;scanf("%d %d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
		degree[x]++;degree[y]++;
	}
	for(int i=1;i<=n;++i){
//		cout<<i<<" "<<degree[i]<<"::"<<endl;
		if(degree[i]!=1){
			if(dfs(i,0)){
				flag=true;
			}
			break;
		}
	}
	cout<<(flag?"NO":"YES");
}

标签:10,子树内,int,43,CSP,发送,树根,节点
From: https://www.cnblogs.com/HaneDaCafe/p/18451391

相关文章

  • [1067] Add comments for files in Windows
    CreateashortcutofthefilePressandholdthe[Alt]keyLeftclickmouseandDragtheselectedfolders/itemstoa"freespace"andreleaseMousebuttonnowyouhavecreatedshortcutsOpenthepropertiesofthefileshortcut,thencanaddt......
  • 在Windows 10中,您可以使用以下命令来转换系统版本(例如,从家庭版升级到专业版)。主要使用
    在Windows10中,您可以使用以下命令来转换系统版本(例如,从家庭版升级到专业版)。主要使用的是slmgr和DISM工具。以下是相关命令:1. 查看当前版本和激活状态bashCopyCodeslmgr/dli2. 输入新产品密钥bashCopyCodeslmgr/ipk<新产品密钥>请将<新产品密钥>替换为您要升......
  • windows@win10@Win11版本号和代号命名变迁@获取或查看windows版本号信息详情方法列举
    文章目录相关文档或参考变迁概况Windows版本号及命名变迁Windows版本及其代号命名变迁分析大版本换代与构建版本变更节点关键点总结查看windows系统的版本号......
  • 2024-10-8
    X9MQ8ML8U7-eyJsaWNlbnNlSWQiOiJYOU1ROE1MOFU3IiwibGljZW5zZWVOYW1lIjoic2lnbnVwIHNjb3R0ZXIiLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoiIiwibGljZW5zZVJlc3RyaWN0aW9uIjoiIiwiY2hlY2tDb25jdXJyZW50VXNlIjpmYWxzZSwicHJvZHVjdHMiOlt7ImNvZGUiOiJJSSIsImZhbGxiYWNrRGF0......
  • 【2024-10-03】连岳摘抄
    23:59我生平最受用的有两句话:一是“责任心”,二是“趣味”。我自己常常力求这两句话之实现与调和,又常常把这两句话向我的朋友强聒不舍。今天所讲,敬业即是责任心,乐业即是趣味。我深信人类合理的生活应该如此,我望诸君和我一同受用!                ......
  • 【2024-10-04】连岳摘抄
    23:59人生价值是一个分数值,取之于社会为分母,反馈于社会为分子。每个人分数值高,加到一起,社会就进步快。                                                 ——田昭武8......
  • 【2024-10-02】连岳摘抄
    23:59为什么我的眼里常含泪水?因为我对这土地爱得深沉......                                                 ——艾青一、恭喜你及时回头,女性35岁,婚育还来得及,再迟......
  • 25N10-智能调光N通道MOS管--HG024N10L 100V 25A 低Vth 低结电容 开关损耗小
    25N10-智能调光N通道MOS管工作原理主要依赖于栅极电压来控制导电沟道的状况。具体来说:工作原理:当加在MOS管栅极上的电压改变时,PN结之间的沟道内载流子的数量会随之改变,沟道电阻也会发生改变,进而控制漏极电流的大小。N沟道MOS管:N沟道加强型MOS管需在栅极上施加正向偏压,且栅源电压大......
  • mysql数据库1045报错怎么解决
    遇到MySQL数据库 1045 报错(访问被拒绝,用户名或密码错误),可以通过以下步骤解决:1.确认用户名和密码检查用户名和密码:确认在连接数据库时输入的用户名和密码是否正确。尝试在命令行中连接数据库,确认是否能成功登录:bash mysql-uyour_username-p2.重置密码......
  • 【2024-10-01】连岳摘抄
    23:59大雨落幽燕,白浪滔天。秦皇岛外打鱼船。一片汪洋都不见,知向谁边?往事越千年,魏武挥鞭,东临碣石有遗篇。萧瑟秋风今又是,换了人间。                                             ......