CF1029E Tree with Small Distances
LXIII.CF1029E Tree with Small Distances
我们发现,如果一个点与连了边,那么它的儿子们以及它的父亲都会变成合法的。
因此我们可以设表示:的某个儿子中有边/自己有边/的父亲应该有边的最小值。
转移:
:可以从儿子的或转移,且儿子中至少有一个为(即,找到与差最小的那个换成)
:皆可,取即可。
:取。
复杂度。
最后说一下答案,应该是的所有儿子的的和,因为的所有儿子都相当于连了一条免费的边。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,head[1001000],cnt,f[1001000][3],res;//0:have a son;1:itself;2:have a father
struct node{
int to,next;
}edge[2001000];
void ae(int u,int v){
edge[cnt].next=head[u],edge[cnt].to=v,head[u]=cnt++;
}
void dfs(int x,int fa){
int mn=0x3f3f3f3f;
f[x][1]=1;
for(int i=head[x],y;i!=-1;i=edge[i].next){
if((y=edge[i].to)==fa)continue;
dfs(y,x);
f[x][0]+=min(f[y][0],f[y][1]),mn=min(mn,f[y][1]-f[y][0]);
f[x][1]+=min(f[y][0],min(f[y][1],f[y][2]));
f[x][2]+=min(f[y][0],f[y][1]);
if(x==1)res+=f[y][1]-1;
}
f[x][0]+=max(mn,0);
}
int main(){
scanf("%d",&n),memset(head,-1,sizeof(head));
for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),ae(x,y),ae(y,x);
dfs(1,0);
printf("%d\n",res);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?