【图论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.mzph.cn/news/91065.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S:pod控制器详解

文章目录 一.pod控制器的基础&#xff11;.pod概念及分类&#xff12;.什么是Pod控制器及其功用&#xff13;.pod控制器有多种类型&#xff08;1&#xff09;ReplicaSet&#xff08;2&#xff09;Deployment&#xff08;3&#xff09;DaemonSet&#xff08;4&#xff09;Statef…

python time和datetime的常用转换处理

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了&#xff0c;直接在文末名片自取就可 一、time 1、…

第一部分:HTML5

目录 一&#xff1a;网页 1.1&#xff1a;什么是网页&#xff1f; 1.2&#xff1a;什么是HTML&#xff1f; 1.3&#xff1a;网页的形成 二&#xff1a;常用浏览器 三&#xff1a;Web标准 3.1&#xff1a;为什么需要Web标准&#xff1f; 3.2&#xff1a;Web标准的构成 四&a…

自动群发节日祝福,1 行 Python 代码搞定,小白可用

想了解更多精彩内容&#xff0c;快来关注程序员晚枫 大家节日快乐&#xff0c;这里是程序员晚枫&#xff0c;小红薯也叫这个名字。 今天给大家分享一个实用功能&#xff1a;自动群发祝福消息。 我相信社会人都体会过&#xff0c;过年过节给别人群发祝福消息的无奈&#xff0…

Cloudflare进阶技巧:缓存利用最大化

1. 引言 cloudflare我想你应该知道是什么&#xff0c;一家真正意义上免费无限量的CDN&#xff0c;至今未曾有哥们喷它的。当然&#xff0c;在国内的速度确实比较一般&#xff0c;不过这也不能怪它。 CDN最大的特色&#xff0c;我想就是它的缓存功能&#xff0c;达到防攻击&am…

C#解析JSON详解

C#解析Json详解 文章目录 C#解析Json详解什么是Json&#xff1f;Json的特点 常用的Json库Json.NET (Newtonsoft.Json)System.Text.Json 实例序列化反序列化 总结 什么是Json&#xff1f; JSON的全称是JavaScript Object Notation&#xff0c;是一种轻量级的数据交换格式&#…

抖音短视频seo矩阵系统源代码开发系统架构及功能解析

短视频seo源码&#xff0c;短视频seo矩阵系统底层框架上支持了从ai视频混剪&#xff0c;视频批量原创产出&#xff0c;云存储批量视频制作&#xff0c;账号矩阵&#xff0c;视频一键分发&#xff0c;站内实现关键词、短视频批量搜索排名&#xff0c;数据统计分类多功能细节深度…

spark Structured报错解决

报错&#xff0c;不想看原因的直接去解决方案试试 Exception in thread "main" java.lang.IllegalArgumentException: Pathname /C:/Users/Administrator/AppData/Local/Temp/1/temporary-611514af-8dc5-4b20-9237-e5f2d21fdf88/metadata from hdfs://master:8020/C…

我的国庆回家之路

文章目录 回家的计划假期的礼物学习新技术与家人团聚遇到的趣事总结 &#x1f389;欢迎来到IT陈寒的博客空间~我的国庆回家之路 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1…

作用域 CSS 回来了

几年前&#xff0c;消失的作用域 CSS&#xff0c;如今它回来了&#xff0c;而且比以前的版本要好得多。 更好的是&#xff0c;W3C规范基本稳定&#xff0c;现在Chrome中已经有一个工作原型。我们只需要社区稍微关注一下&#xff0c;引诱其他浏览器构建它们的实现&#xff0c;并…

【教学类-35-03】学号+姓名+班级(小3班)学号字帖(A4竖版2份)

图片展示: 背景需求: 本周排到小3班&#xff0c;还没有来得及设计小班主题活动书的内容&#xff0c;于是就把小2班的学号字帖微调一下&#xff0c;做一份竖版2份的学号字帖。 让幼儿熟悉自己的学号&#xff0c;让我也熟悉幼儿的名字和学号 材料准备&#xff1a; 描字写&#…

基于微信小程序的二手闲置交易市场小程序设计与实现(源码+lw+部署文档+讲解等)

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

【owt-server】fix : node-gyp configure 报错:Error: read ECONNRESET

npm已经设置了registry 还报错 npm config set registry http://registry.npmmirror.comnode-gyp configure 指令 node-gyp configure 报错 read ECONNRESET root@k8s-master-2K4G:~/p2p/zdsvr-20201229# ./scripts/build.js -t mcu --check /root/p2p/zdsvr-20201229/build/li…

【算法分析与设计】动态规划(下)

目录 一、最长公共子序列1.1 最长公共子序列的结构1.2 子问题的递归结构1.3 计算最优值1.4 举例说明1.5 算法的改进 二、最大子段和2.1 代码2.2 最大子段和问题的分治算法2.3 代码2.4 分治算法的时间复杂度2.5 最大子段和问题的动态规划算法 三、凸多边形最优三角剖分3.1 三角剖…

Spring cloud Sentinel介绍和安装

Sentinel介绍和安装 &#x1f308;初识Sentinel&#x1f308;安装Sentinel&#x1f320;docker 安装&#x1f320;下载sentinel镜像&#x1f320;启动sentinel镜像 &#x1f320;windows 安装&#x1f320;下载&#x1f320;运行 &#x1f320;sentinel访问 &#x1f308;微服务…

Neo4j-双向关系

概述 这是GraphAware中关于双向关系的解释。 网址链接Modelling Data in Neo4j: Bidirectional Relationships | GraphAware 定向关系 Neo4j中的关系必须有一个语义化的类型和方向。 没有方向关系是模棱两可的&#xff0c;上面A队打败B队&#xff0c;如果没有方向&#xff0c…

【数据结构】什么是数据结构?

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 &#x1f38f;数据结构的定义 &#x1f38f;结语 &#x1f38f;数据结构的定义 数据结构(Data Structure)是计算机存储,组织数据的方式,指相互之间存在一种或多种特定关…

【自监督Re-ID】ICCV_2023_Oral | ISR论文阅读

Codehttps://github.com/dcp15/ISR_%20ICCV2023_Oral 面向泛化行人再识别的身份导向自监督表征学习&#xff0c;清华大学 目录 导读 摘要 相关工作 DG ReID 用于ReID的合成数据 无监督表征学习 Identity-Seeking Representation Learning 结果 消融实验 导读 新角度…

Linux常见指令2

Linux常见指令[2] 一.Linux常见指令1.man补充知识:nano 2.cp3.mv4.cat补充知识:echo输出重定向追加重定向回到catcat其他用法 5.less和more补充内容回到less 6.head和tail补充知识:命令行管道 一.Linux常见指令 前言:为了方便我们在Linux中写指令 介绍一下: 1.clear指令: 清屏…

【小沐学C++】C++ 基于Premake构建工程项目(Windows)

文章目录 1、简介2、下载和安装2.1 下载2.3 快速入门 3、使用3.1 支持的工程文件Project Files3.2 构建设置Build Settings3.3 链接Linking3.4 配置Configurations3.5 平台Platforms3.6 过滤Filters3.7 预设值Tokens 4、测试4.1 测试1&#xff1a;入门例子4.2 测试2&#xff1a…