当前位置: 首页 > news >正文

【树\思维】P1395 会议

题目描述

有一个村庄居住着 nnn 个村民,有 n−1n-1n1 条路径使得这 nnn 个村民的家联通,每条路径的长度都为 111。现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地点设置在哪个村民的家中,并且这个距离总和最小是多少?若有多个节点都满足条件,则选择节点编号最小的那个点。

输入格式

第一行,一个数 nnn,表示有 nnn 个村民。

接下来 n−1n-1n1 行,每行两个数字 aaabbb,表示村民 aaa 的家和村民 bbb 的家之间存在一条路径。

输出格式

一行输出两个数字 xxxyyy

xxx 表示村长将会在哪个村民家中举办会议。

yyy 表示距离之和的最小值。

输入输出样例

输入 #1
4
1 2 
2 3 
3 4
输出 #1
2 4

说明/提示

对于 70%70\%70% 数据 n≤103n \le 10^3n103

对于 100%100\%100% 数据 n≤5×104n \le 5 \times 10^4n5×104

思路

考虑以节点 111 为根节点建立树,并用 dfs 求出每个节点子树的节点个数,记作 sonison_isoni,同步可以求出以 111 为会议地点所需的距离总和,只需要在回溯时将 ansdis←ansdis+sonians_{dis} \gets ans_{dis}+son_iansdisansdis+soni 即可,代表所有属于该节点为根的子树的节点全部需要多走 111 个单位长度才能到达该节点的父亲节点。

我们考虑会议地址不在 111 上的情况,不妨令 ttt111 的其中一个子节点,则容易发现,当我们把会议地址从 111 换到 ttt 的时候, ttt 所有子树上的节点到会议地址的距离都少了 111,整个树上不在以 ttt 为根的子树上的其他节点到会议地址的距离都加了 111,故转移可以写为:

ansdis=min⁡(ansdis,ansdis+sont−(son1−sont))ans_{dis}=\min(ans_{dis},ans_{dis} +son_t-(son_1-son_t))ansdis=min(ansdis,ansdis+sont(son1sont))

对于子树转移同理,只需要运行 222dfs 算法,每次都遍历一整个大小为 nnn 的树,总共时间复杂度为 O(n)O(n)O(n)

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,head[50005],nex[100005],to[100005],cnt = 0;
void add(int x,int y) {nex[++cnt] = head[x];head[x] = cnt;to[cnt] = y;
}
int son[50005]; 
int ans_point,ans_dis;
void dfs(int now,int fa) {son[now]++;for(int i = head[now];i;i = nex[i]) {if(to[i] != fa) {dfs(to[i],now);son[now] += son[to[i]];ans_dis += son[to[i]];}}
}
void find_ans(int now,int fa,int dis) {if(now != 1) {dis -= son[now];dis += (son[1] - son[now]);if(dis < ans_dis or (dis == ans_dis and ans_point > now)) {ans_dis = dis,ans_point = now;}}for(int i = head[now];i;i = nex[i]) {if(to[i] != fa) {find_ans(to[i],now,dis);}}
}
signed main() {scanf("%lld",&n);for(int i = 1;i < n;i++) {int x,y;scanf("%lld %lld",&x,&y);add(x,y),add(y,x);}dfs(1,1);ans_point = 1;find_ans(1,1,ans_dis);printf("%lld %lld\n",ans_point,ans_dis);return 0;
}
http://www.dtcms.com/a/324851.html

相关文章:

  • 33.搜索旋转排序数组
  • Agno智能体框架简单使用
  • docker等基础工具使用
  • 从策略梯度到 PPO
  • java中的继承
  • Flutter开发 LinearProgressIndicato、CircularProgressIndicator
  • django基于Python的设计师作品平台的数据可视化系统设计与实现
  • QT的常用控件说明
  • Java基础—解析注解
  • 游戏常用运行库合集:一键解决游戏兼容性问题
  • 锂电池SOH预测 | 第35讲 Matlab基于BiLSTM的锂电池健康状态估计(锂电池SOH预测),附锂电池最新文章汇集
  • scanpy单细胞转录组python教程(二):单样本数据分析之数据质控
  • springboot的基础要点
  • 【Task3】【Datawhale AI夏令营】多模态RAG
  • 3.4路由守卫
  • Words or Vision Do Vision-Language Models Have Blind Faith in Text
  • Java中new的相关知识
  • nginx-主配置文件
  • Redis的批处理优化
  • 【高等数学】第八章 向量代数与空间解析几何——第六节 空间曲线及其方程
  • ECP HRFORM 提示ADS服务异常
  • 【嵌入式电机控制#补充3】SDK电机控制台的功能
  • C9800在NAT设备之后怎么办?
  • [创业之路-541]:经营分析会 - 企业的经营分析会,研发负责人负责提供哪些信息?
  • Linux810 shell 条件判断 文件工具 ifelse
  • 【牛客刷题】小红的项链(字节跳动面试题)
  • Linux操作系统从入门到实战(十七)进程与进程基本概念
  • doubletrouble靶机攻略
  • Docker 数据卷的核心原理与管理逻辑
  • 【数据结构与算法-Day 14】先进先出的公平:深入解析队列(Queue)的核心原理与数组实现