CF2018C Tree Pruning 题解

embedded/2024/10/11 1:08:38/

Description

给定一棵有 n n n 个点的以 1 1 1 为根的树,在此问题中,叶子节点被定义为非根的度数为一的点。

每次操作可以删去一个叶子节点及其相连的边,你需要求出最小的操作次数,使得操作后所有叶子节点到根节点的距离相同。

Solution

考虑一条边什么情况下不会被删去。

对于 ( x , y ) (x,y) (x,y) 这条边,设 y y y 为深度较大的那个点, z z z y y y 子树内深度最大的点,那么只要操作完后的叶子深度在 [ d e p y , d e p z ] [dep_y,dep_z] [depy,depz] 范围内,那么这条边就不会被删去,对区间 [ d e p y , d e p z ] [dep_y,dep_z] [depy,depz] 1 1 1 即可,最后叶子深度则为所有可能深度中被加次数最大的那个深度,答案为边数减去其被加的次数。

发现这是区间加,单点查询,你可以用你喜欢的数据结构维护,如线段树、树状数组、分块等。

代码用线段树实现,复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls x<<1
#define rs x<<1|1
int t;
int n,tot;
int head[1000010],dep[1000010];
struct edge{int to,next;
}e[1000010];
void add(int x,int y){e[++tot]=edge{y,head[x]};head[x]=tot;
}
struct tree{int sum;
}tr[2000020];
void build(int x,int l,int r){tr[x].sum=0;if(l==r) return ;int mid=l+r>>1;build(ls,l,mid);build(rs,mid+1,r);
}
void update(int x,int l,int r,int L,int R){if(l>=L&&r<=R){tr[x].sum++;return ;}int mid=l+r>>1;if(L<=mid) update(ls,l,mid,L,R);if(R>=mid+1) update(rs,mid+1,r,L,R);
}
int query(int x,int l,int r,int k){if(l==r) return tr[x].sum;int mid=l+r>>1,ans=tr[x].sum;if(k<=mid) return ans+query(ls,l,mid,k);else return ans+query(rs,mid+1,r,k);
}
int dfs(int x,int fax){dep[x]=dep[fax]+1;int maxn=dep[x];for(int i=head[x];i;i=e[i].next){int y=e[i].to;if(y==fax) continue;int z=dfs(y,x);update(1,1,n,dep[x]+1,z);maxn=max(maxn,z);}return maxn;
}
void init(){tot=0;for(int i=1;i<=n;i++){head[i]=0;}build(1,1,n);
}
void solve(){cin>>n;init();for(int i=1;i<n;i++){int x,y;cin>>x>>y;add(x,y),add(y,x);}dfs(1,0);int ans=0;for(int i=1;i<=n;i++){ans=max(ans,query(1,1,n,i));}cout<<n-1-ans<<'\n';
}
int main(){ios::sync_with_stdio(0);cin.tie(nullptr);cin>>t;while(t--){solve();}return 0;
}

http://www.ppmy.cn/embedded/125643.html

相关文章

变换器(Transformer)在医学成像中的应用(上)

在自然语言任务上取得前所未有的成功之后&#xff0c;Transformer已被成功应用于多个计算机视觉问题&#xff0c;取得了最先进的结果&#xff0c;并促使研究人员重新考虑卷积神经网络(CNNs)作为事实上标准操作符的优势地位。利用计算机视觉领域的这些进展&#xff0c;医学影像领…

byte[]/InputStream/MultipartFile之间进行转换

前言 问题产生&#xff1a; 最近开发项目的时候&#xff0c;遇到了文件上传对象转换的问题 -> 我在对接抖音开放平台的时候&#xff0c;有一个图片上传的接口&#xff0c;需要将byte[]转为MultipartFile 对象&#xff0c;但是发现根本没有这样的工具类&#xff0c;后面翻阅…

[k8s理论知识]1.runc容器管理工具

runc是一个用来启动和管理容器的轻量级工具&#xff0c;它是开放容器项目(Open Container Initiative, OCI)的标准实现。runc 是一个 CLI 工具&#xff0c;用于根据 OCI 规范创建和运行容器。它是容器底层的核心组件&#xff0c;负责直接与 Linux 内核的 cgroups 和 namespaces…

MinIO分片上传超大文件(纯服务端)

目录 一、MinIO快速搭建1.1、拉取docker镜像1.2、启动docker容器 二、分片上传大文件到MinIO2.1、添加依赖2.2、实现MinioClient2.3、实现分片上传2.3.0、初始化MinioClient2.3.1、准备分片上传2.3.2、分片并上传2.3.2.1、设置分片大小2.3.2.2、分片 2.3.3、分片合并 三、测试3…

python xml的读取和写入

import xml.etree.ElementTree as ET from xml.dom import minidom# 读取XML文档 tree ET.parse("./xml_3/z_20240827_001.xml") root tree.getroot() # 获取size元素 size_find_0 root.find("size") # 获取width子元素 size_w size_find_0.find("…

Cocos_鼠标滚轮放缩地图

文章目录 前言一、环境二、版本一_code2.分析类属性方法详细分析详细分析onLoad()onMouseWheel(event)详细分析 总结 前言 学习笔记&#xff0c;请多多斧正。 一、环境 通过精灵rect放置脚本实现鼠标滚轮放缩地图。 二、版本一_code import { _decorator, Component, Node }…

《Java程序员面试宝典》——(第二章节)

当前因为经济大环境不好、大厂裁员、就业情况差、企业要求变高、各行各业越来越卷&#xff0c;尤其是程序员&#xff0c;处于这个阶段&#xff0c;感觉特别明显&#xff01; 对于程序员这个群体来说&#xff0c;java程序员的占比就非常之高&#xff0c;就业市场等于说是千军万…

51单片机的无线通信智能车库门【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块红外传感器光照传感器时钟模块步进电机蓝牙按键、LED、蜂鸣器等模块构成。适用于智能车库自动门、无线控制车库门等相似项目。 可实现功能: 1、LCD1602实时显示北京时间和自动/手动模式&#xff0c;以及验证是否成…