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

洛谷 P1395 会议 -普及/提高-

P1395 会议

题目描述

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

输入格式

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

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

输出格式

一行输出两个数字 xxxyyy

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

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

输入输出样例 #1

输入 #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

solution

  • 思路: 其实就是重心,任选一个节点作为 root,第一遍dfs算出各节点子树节点到该节点的距离和,和子树节点个数,第二遍dfs在考虑上从父节点过来的分支距离
  • 具体:
    • 1 设
      f[u]: 以u为根的子树节点距离和,
      siz[u]:以u为根的子树节点个数
      g[u]: 的所有节点到u的距离和
  • 2 递推:v 是 u 的子节点
    • dfs(1, 0)
    •  siz[u] += siz[v];f[u] += siz[v] + f[v];
      
    • dfs2(1, 0)
    •    g[1] = f[1]g[v] = g[u] + (n - 2 * siz[v]);
      

代码

#include<iostream>
#include<algorithm>
#include "cstring"
#include "vector"using namespace std;/** P1395 会议* 题目大意: 有一颗无根无权树,找到树中一个节点,使得其它所有节点的到该点的距离和最小** 思路: 其实就是重心,任选一个节点作为 root,第一遍dfs算出各节点子树节点到该节点的距离和,和子树节点个数* 第二遍dfs在考虑上从父节点过来的分支距离* 具体:* 1 设 f[u]: 以u为根的子树节点距离和,siz[u]:以u为根的子树节点个数,*      g[u]: 的所有节点到u的距离和* 2 递推:v 是 u 的子节点*   dfs(1, 0)*      siz[u] += siz[v];*      f[u] += siz[v] + f[v];*   dfs2(1, 0)*      g[1] = f[1]*      g[v] = g[u] + (n - 2 * siz[v]);**/typedef long long ll;
const int N = 5e4 + 5;int n, siz[N], f[N], g[N], Min, k;
vector<int> e[N];void dfs(int u, int p) {siz[u] = 1;for (int v: e[u]) {if (v == p) continue;dfs(v, u);siz[u] += siz[v];f[u] += siz[v] + f[v];}
}void dfs2(int u, int p) {for (int v: e[u]) {if (v == p) continue;g[v] = g[u] + (n - 2 * siz[v]);if (g[v] < Min || g[v] == Min && v < k) k = v, Min = g[v];dfs2(v, u);}
}int main() {cin >> n;for (int i = 1, x, y; i < n; i++) {cin >> x >> y;e[x].push_back(y);e[y].push_back(x);}dfs(1, 0);Min = f[1], k = 1, g[1] = f[1];dfs2(1, 0);cout << k << ' ' << Min << endl;return 0;
}

结果

在这里插入图片描述

http://www.dtcms.com/a/359258.html

相关文章:

  • 吴恩达机器学习(四)
  • 10. 函数和匿名函数(二)
  • 深入理解 shared_ptr 与 weak_ptr:访问控制与线程安全
  • 广东省省考备考(第九十天8.30)——判断推理(第十节课)
  • Java多线程初阶
  • C++讲解---如何设计一个类
  • 防火墙技术(三):状态检测和会话机制
  • 接口自动化测试框架
  • python pyqt5开发DoIP上位机【自动化测试的逻辑是怎么实现的?】
  • 深度解析Fluss LockUtils类的并发艺术
  • 手写MyBatis第43弹:插件拦截原理与四大可拦截对象详解
  • Agent实战教程:LangGraph结构化输出详解,让智能体返回格式化数据
  • Keil5 MDK_541官网最新版下载、安装
  • offsetof宏的实现
  • 线程池项目代码细节2
  • 互联网医院系统源码解析:如何从零搭建高效的在线问诊平台
  • SNMPv3开发--EngineID安全访问机制
  • 腾讯云的运维笔记——从yum的安装与更新源开始
  • 深入理解 Linux 驱动中的 file_operations:从 C 语言函数指针到类比 C++ 虚函数表
  • centos7中MySQL 5.7.32 到 5.7.44 升级指南:基于官方二进制包的原地替换式升级
  • 有个需求:切换车队身份实现Fragment的Tab隐藏显示(车队不显示奖赏)
  • SNMPv3开发--简单使用
  • 【Linux基础】深入理解Linux环境下的BIOS机制
  • Python - 机器学习:从 “教电脑认东西” 到 “让机器自己学规律”
  • 项目管理和产品管理的区别
  • docker,mysql安装
  • vector的学习和模拟
  • 揭秘表格推理的“思维革命”:RoT模型介绍
  • 【机器学习基础】机器学习中的容量、欠拟合与过拟合:理论基础与实践指南
  • Vue生命周期、工程化开发和脚手架、组件化开发