【图论C++】树的重心——教父POJ 3107(链式前向星的使用)

》》》算法竞赛

/*** @file            * @author          jUicE_g2R(qq:3406291309)————彬(bin-必应)*						一个某双流一大学通信与信息专业大二在读	* * @brief           一直在竞赛算法学习的路上* * @copyright       2023.9* @COPYRIGHT			 原创技术笔记:转载需获得博主本人同意,且需标明转载源* @language        C++* @Version         1.0还在学习中  */
  • UpData Log👆 2023.9.26 更新进行中
  • Statement0🥇 一起进步
  • Statement1💯 有些描述是个人理解,可能不够标准,但能达其意

技术提升站点

文章目录

  • 》》》算法竞赛
  • 技术提升站点
  • 21 树上问题
    • 21-0 关于 树 的问题 有哪些?
    • 21-1 树的重心
      • 21-1-1 重心是什么?
      • 21-1-2 重心的性质
      • 21-1-2 重心的查找
  • 教父(poj 3107)

21 树上问题

  • 的一种特例 就是 “没有环”连通图

判断一个 是否是一个 ,需要满足的条件:

  • 1)树根:一棵树可以基于无向图有向图,区别在于树根。

    基于无向图的树(无根树),是没有固定树根的(也就是说树根的个数可能不止为1,或说每个结点都能做为树根)

    基于有向图的树(有根树),有且仅有一个树根

  • 2)父节点与子节点的关系:每个节点有且仅有一个父节点。从根节点遍历,必须由父节点遍历到子节点

  • 3)连通性:从 根 出发可以遍历树上所有(除根节点外)节点,且到这些节点的路径只有一条

有根树 与 有向无环图 DAG 的 区别

有向无环图:不能从某点开始经过数点回到该点

有根树 都是 DAGDAG 不一定是 有根树(如下图:虽然没有构成环,但是4号节点同时拥有两个父节点,不符合有根树的定义)

21-0 关于 树 的问题 有哪些?

直通车:

  • 树的判断:判定 图 是否为 树 的方法是 DFS遍历
  • 树的存储:与 图 的存储方式一致(链式前向星)
  • 树的路径问题(包含了 查找最近公共祖先LCA):点击直通 树的路径问题
  • 树的直径
  • 树的重心(下文将讲解)
  • 多叉树、二叉树
  • 树上前缀和,树上差分

21-1 树的重心

21-1-1 重心是什么?

  • 树的重心 适用在 无根树(一个不含回路的无向图)
  • 树的重心 是 以任意结点 u 为根 计算它最大子树的节点数 n o d e n node_n noden,如果 u节点 n o d e n node_n noden 最少,则 u节点 为 树的重心。

可以一眼看出:4号结点 就是 树的重心,因为这个点能满足 n o d e n node_n noden 是最小的(左子树{4,2,1,3,}:4个,右子树{4,5,6,7}:4个),而其他任意一个节点的子树(例如 2号节点的最大子树{2,4,5,6,7}5个)都是比这个点的最大子树的节点数是大的。

21-1-2 重心的性质

  • 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。(树上分治会用到
  • 树的重心如果不唯一,则至多有两个,且这两个重心相邻
  • 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样
  • 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上
  • 在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。(往树上增加或减少一个叶子,如果原节点数是奇数,那么重心可能增加一个,原重心仍是重心;如果原节点数是偶数,重心可能减少一个,另一个重心仍是重心

21-1-2 重心的查找

教父(poj 3107)

问题描述

城里有一个黑手党组织。把黑手党的人员关系用一棵树来描述,教父是树的根,每个节点是一个组织成员。为了保密,每人只和他的父节点和他的子节点联系。警察知道哪些人互相来往,但是不知他们的关系。警察想找出谁是教父
警察假设教父是一个聪明人:教父懂得制衡手下的权力,所以他直属的几个小头目,每个人的属下的人数差不多。也就是说,删除根之后,剩下几棵互不连通的子树(连通块),其中最大的连通块应该尽可能小。请帮助警察找到哪些人可能是教父。
输入:第1行输入n,表示组织人数, 2 ≤ n ≤ 50000 2\leq n \leq 50000 2n50000 。组织成员的编号为1~n。下面n-1行中,每行输入两个整数,即有联系的两个人的编号。
输出:输出疑似教父的节点编号,从小到大输出。

Input

6
1 2
2 3
2 5
3 4
3 6

Output

2 3
  • 分析

“删除根之后,剩下几棵互不连通的子树(连通块),其中最大的连通块应该尽可能小”,这句话说明了 教父 就是 这个关系树里的 重心

如何计算以 u节点 为根的子树的结点

u节点 DFS 直到“碰壁”后,将栈里的数据依次弹出,弹出一个结点数加1。

那么这样的话,可以对删除根之后,剩下几棵互不连通的子树(连通块) 进行单独的DFS,对整棵树逐一删除节点,重复上述步骤,就能得到每个结点的最大连同块。

如何优化?

上面提出的方案是 使用 暴力法 解决,其实无需如此,可以依照线段树的思维,对 同父节点的子节点 进行合并,得到父节点的子树的节点数,这样一次DFS就可以解决问题。

如上图,假如删除 结点1,得到3个连通块(含结点1的邻居:节点3、含结点1的邻居:节点0、含结点1的邻居:节点4)

对任意点做一次 DFS,特殊点,以 结点2为根节点 做DFS:

从2向0方向 一直DFS,直到遍历到节点10,停止遍历,栈开始弹出数据。,当弹出结点10时,记录 结点10 的度(即子树的结点数) D e g r e e [ 10 ] = 1 Degree[10]=1 Degree[10]=1,同理 D e g r e e [ 9 ] = 1 Degree[9]=1 Degree[9]=1;当弹出4时, D e g r e e [ 4 ] = D e g r e e [ 9 ] + D e g r e e [ 10 ] + 1 = 3 Degree[4]=Degree[9]+Degree[10]+1=3 Degree[4]=Degree[9]+Degree[10]+1=3,同理算出 D e g r e e [ 3 ] = D e g r e e [ 7 ] + D e g r e e [ 8 ] + 1 = 3 Degree[3]=Degree[7]+Degree[8]+1=3 Degree[3]=Degree[7]+Degree[8]+1=3;在弹出1时, D e g r e e [ 1 ] = D e g r e e [ 3 ] + D e g r e e [ 4 ] + 1 = 7 Degree[1]=Degree[3]+Degree[4]+1=7 Degree[1]=Degree[3]+Degree[4]+1=7;删除1后, D e g r e e [ 0 ] = n − D e g r e e [ 1 ] Degree[0]=n-Degree[1] Degree[0]=nDegree[1]

存储:链式前向星

链式前向星领接矩阵(二维数组)在空间上优化了很多

点击直通 链式前向星(图(树)的存储)

  • 代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
vector<int> head(N,-1);
struct Edge{int to,next;Edge():to(-1), next(-1){}				        //初始化为无邻居节点
} edge[N<<1];
vector<int> Degree(N,1);                            //初始化每个节点的度(子树的结点数)为1
int edge_n=0;                                       //记录边数
int GodFather_n=0;                                  //记录可能得教父个数
int n;                                              //人有n个,关系有n-1条
int MAX_Degree=1e9;
vector<int> ans(N,0);
void Add_Edge(int u, int v){edge[edge_n].to=v;edge[edge_n].next=head[u];                     //记录 上一个邻居节点 的 存储编号head[u]=edge_n++;                              //当前 邻居节点 的 存储编号,以便下一个邻居节点的访问
}
void DFS(int u=1, int father=0){/*计算 cur结点 的 最大连通块的结点数*/int temp=0;for(int i=head[u]; ~i; i=edge[i].next){         //遍历cur节点的邻居节点[~i相当于i=-1]int v=edge[i].to;                           //v 是 u 的子节点if(v==father)     continue;DFS(v,u);                                   //DFS子树Degree[u]+=Degree[v];                       //更新父节点的度temp=max(temp, Degree[v]);                  //记录cur结点的 最大子树 的 结点数}temp=max(temp, n-Degree[u]);                    //temp是cur最大连通块的节点数/*查找 结点数 最小的 最大连通块*/if(temp<MAX_Degree){                            //满足条件的话,则temp是 疑似教父 的最大连通块的结点数MAX_Degree=temp;                            //更新 最小的 最大连通块GodFather_n=0;                              //找到新的最小,将它放在第一个ans[++GodFather_n]=u;}else if(temp==MAX_Degree)ans[++GodFather_n]=u;
}int main(int* argc, void* argv[]){cin>>n;for(int i=1; i<n;i++){int u,v;    cin>> u >> v;Add_Edge(u,v);  Add_Edge(v,u);              //无向 记录 双向有向}DFS();sort(ans.data()+1, ans.data()+1+GodFather_n);   //升序排列for(int i=1; i<=GodFather_n; i++)cout<<ans[i]<<" ";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145445.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯mini项目-【指标监控服务重构-会议记录】2023-07-21

2023-07-21 组长会议纪要 A组 文档学习差不多&#xff0c;还没掌握如何使用sdk进行上报venus启动服务的3个ToDo 添加什么错误处理 ErrHandler &#xff1a; fiber的错误处理&#xff0c;是运行过程Handler中的错误&#xff0c;在全局的ErrHandler&#xff0c;进行错误处理&am…

app专项测试:app弱网测试

背景 用户体验 APP使用过程中&#xff0c;弱网的高延迟和高丢包&#xff0c;在实时性要求非常高的场景&#xff0c;容易伤害用户体验 非正常情况下&#xff0c;Bug出现几率会增加 在解决日常支持需求中&#xff0c;经常出现一些用户反馈的Bug无法复现&#xff0c;有很大部分…

线性代数(七) 矩阵分析

前言 从性线变换我们得出&#xff0c;矩阵和函数是密不可分的。如何用函数的思维来分析矩阵。 矩阵的序列 通过这个定义我们就定义了矩阵序列的收敛性。 研究矩阵序列收敛性的常用方法&#xff0c;是用《常见向量范数和矩阵范数》来研究矩阵序列的极限。 长度是范数的一个特…

三翼鸟三周年:三次升级,全面引领

被誉为“竞争战略之父”的迈克尔波特&#xff0c;曾提出过“差异化竞争”的理念。 简单说&#xff0c;企业在“差异化竞争”中要做到三大法则&#xff1a; 人无我有、人有我优、人有我新。 在许多优秀企业的身上&#xff0c;都能看到差异化的影子&#xff0c;比如华为、海尔…

CentOS 7 安装 Docker 的详细步骤

文章目录 Docker简介1.更新2.安装必要的软件包3.添加Docker仓库4.安装5.安装后的一些常规设置及常用的命令5.1 启动 Docker5.2 Docker 在系统启动时自动运行5.3 运行一个 Hello World 镜像5.4 查看docker运行状态5.5 docker ps5.6 查看docker版本 6.安装种常见的错误错误1:yum-…

黑马程序员Docker快速入门到项目部署(学习笔记)

目录 一、Docker简介 二、安装Docker 2.1、卸载旧版 2.2、配置Docker的yum库 2.3、安装Docker 2.4、启动和校验 2.5、配置镜像加速 2.5.1、注册阿里云账号 2.5.2、开通镜像服务 2.5.3、配置镜像加速 三、快速入门 3.1、部署MYSQL 3.2、命令解读 四、Docker基础 …

【分布式云储存】Springboot微服务接入MinIO实现文件服务

文章目录 前言技术回顾准备工作申请accessKey\secretKey创建数据存储桶公共资源直接访问测试 接入springboot实现文件服务依赖引入配置文件MinIO配置MinIO工具类 OkHttpSSLSocketClient兼容ssl静态资源预览解决方案资源上传预览测试测试结果 前言 上篇博客我们介绍了分布式云存…

day06_循环

今日内容 零、 复习昨日 一、循环 二、流程控制关键词 零、 复习昨日 8个基本数据类型 变量的使用步骤 1)声明2)赋值3)使用 声明,数据类型 变量名 不一定非得是基本类型 int a; String s; Scanner scanner;赋值,只要符合类型(能默认转换)就能赋值 int a 1; double d 1; Scann…

【KingbaseES】银河麒麟V10 ARM64架构_安装人大金仓数据库KingbaseES_V8R6(CentOS8)

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…

基于Java的毕业设计管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

云部署家里的服务器

1.固定静态ip 查看ip地址&#xff0c;en开头的 ifconfig查看路由器ip&#xff0c;via开头的 ip route修改配置文件 cd /etc/netplan/ #来到这个文件夹 sudo cp 01-network-manager-all.yaml 01-network-manager-all.yaml.bak #先备…

excel筛选后求和

需要对excel先筛选&#xff0c;后对“完成数量”进行求和。初始表格如下&#xff1a; 一、选中表内任意单元格&#xff0c;按ctrlshiftL&#xff0c;开启筛选 二、根据“部门”筛选&#xff0c;比如选择“一班” 筛选完毕后&#xff0c;选中上图单元格&#xff0c;然后按alt后&…

泰国数字加密平台Bitkub创始人到访和数集团:以数字化创新探索科技前沿密码

9月21日&#xff0c;泰国数字加密货币交易平台Bitkub创始人兼首席执行官&#xff08;CEO&#xff09;Jirayut Srupsrisopa (Topp)先生到访上海和数集团&#xff0c;在和数集团董事长唐毅陪同下实地参观了和数集团上海总部&#xff0c;听取了和数集团在引领前沿数字化创新&#…

【跟小嘉学习区块链】二、Hyperledger Fabric 架构详解

系列文章目录 【跟小嘉学习区块链】一、区块链基础知识与关键技术解析 【跟小嘉学习区块链】二、区块链基础知识与关键技术解析 文章目录 系列文章目录[TOC](文章目录) 前言一、Hyperledger 社区1.1、Hyperledger(面向企业的分布式账本)1.2、Hyperledger社区组织结构 二、Hype…

结构型设计模式——组合模式

摘要 组合模式(composite pattern): 允许你将对象组合成树形结构来表现"整体/部分"层次结构. 组合能让客户以一致的方式处理个别对象以及对象组合。 一、组合模式的意图 将对象组合成树形结构来表示“整体/部分”层次关系&#xff0c;允许用户以相同的方式处理单独…

性能测试工具 — JMeter

一、JMeter准备工作 1、JMeter介绍 Apache JMeter 应用程序是开源软件&#xff0c;是一个 100% 纯 Java 应用程序。用于测试Web应用程序、API和其他网络协议的性能。它具有以下特点&#xff1a; 1. 开源免费&#xff1a;JMeter是Apache软件基金会下的一个开源项目&#xff0…

〔025〕Stable Diffusion 之 接口开发 篇

✨ 目录 🎈 启动接口🎈 接口文档🎈 接口开发🎈 代码解释🎈 启动接口 想要在各种其他服务中对接 Stable Diffusion 的绘画功能,需要开启 Stable Diffusion 的 api 功能开发接口需要有一定的技术功底才可以,非技术人员其实不用学习直接在 webui-user.bat 文件中的 se…

【Flink】

事件驱动型应用 核心目标&#xff1a;数据流上的有状态计算 Apache Flink是一个框架和分布式处理引擎&#xff0c;用于对无界或有界数据流进行有状态计算。 运行逻辑 状态 把流处理需要的额外数据保存成一个“状态”,然后针对这条数据进行处理,并且更新状态。这就是所谓的“…

电脑突然提示mfc140u.dll丢失,缺失mfc140u.dll无法运行程序的解决方法

在当今信息化社会&#xff0c;电脑已经成为我们生活和工作中不可或缺的一部分。然而&#xff0c;随着技术的不断发展&#xff0c;电脑也会出现各种问题。其中&#xff0c;最常见的问题之一就是“mfc140u.dll丢失”。那么&#xff0c;当我们遇到这个问题时&#xff0c;应该如何解…

redis部署与管理

目录 一、关系数据库与非关系型数据库&#xff1a; 1. 关系型数据库&#xff1a; 2.非关系型数据库&#xff1a; 二、关系型数据库和非关系型数据库区别&#xff1a; &#xff08;1&#xff09;数据存储方式不同&#xff1a; &#xff08;2&#xff09;扩展方式不同&#xf…