传送门

题意:给一棵NNN个结点的树,你需要钦定一个根,使得所有深度相同的点的度数相同。

N≤100000N \leq 100000N≤100000

用脑子想一想,就是根节点直接相连的子树都长得一模一样。

如果根节点度数大于1,我们发现它把整棵树均匀地分成了若干份。所以根节点是重心。

O(N)O(N)O(N)找重心检查一下

如果根节点度数等于1,也就是拉了一条链下去

由于是递归的,所以走到有岔路的地方就是岔路口所在子树的重心

因为两棵树合并后的重心在原来的重心的路径上,所以整棵树的重心在链上。

所以沿一条链走到底就可以了。

但如果有多条路,说明重心是岔路口。因为下面长得一模一样,所以即使是链,长度也都相同。

所以找两条长度不同的链的顶部搜一下即可。

复杂度O(N)O(N)O(N)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 100005
#define MAXM 200005
using namespace std;
struct edge{int u,v;}e[MAXM];
int head[MAXN],nxt[MAXM],cnt;
void addnode(int u,int v)
{e[++cnt]=(edge){u,v};nxt[cnt]=head[u];head[u]=cnt;
}
int siz[MAXN],dep[MAXN],n;
void dfs(int u)
{siz[u]=1;for (int i=head[u];i;i=nxt[i])if (!dep[e[i].v]){dep[e[i].v]=dep[u]+1;dfs(e[i].v);siz[u]+=siz[e[i].v];}
}
int maxp[MAXN]={0x7fffffff};
int findroot()
{dfs(dep[1]=1);int rt=0;for (int u=1;u<=n;u++){for (int i=head[u];i;i=nxt[i])if (dep[e[i].v]==dep[u]+1)maxp[u]=max(maxp[u],siz[e[i].v]);if (n-siz[u]>maxp[u]) maxp[u]=n-siz[u];if (maxp[u]<maxp[rt]) rt=u;}return rt;
}
int tmp[MAXN];
bool check(int rt)
{memset(siz,0,sizeof(siz));memset(dep,0,sizeof(dep));memset(tmp,0,sizeof(tmp));dep[rt]=1;dfs(rt);for (int u=1;u<=n;u++){int deg=0;for (int i=head[u];i;i=nxt[i])++deg;if (!tmp[dep[u]]) tmp[dep[u]]=deg;if (tmp[dep[u]]!=deg) return false;}return true;
}
int line(int u,int f)
{if (!nxt[head[u]]) return u;if (nxt[nxt[head[u]]]) return 0;int i=head[u];if (e[i].v==f) i=nxt[i];return line(e[i].v,u);
}
int len[MAXN];
inline bool cmp(const int& a,const int& b){return dep[a]<dep[b];}
int main()
{scanf("%d",&n);for (int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);addnode(u,v);addnode(v,u);}int rt=findroot();if (check(rt)){printf("%d\n",rt);return 0;}for (int i=head[rt];i;i=nxt[i])len[++len[0]]=line(e[i].v,rt);sort(len+1,len+len[0]+1,cmp);if (len[1]&&check(len[1])){printf("%d\n",len[1]);return 0;}if (len[len[0]]&&check(len[len[0]])){printf("%d\n",len[len[0]]);return 0;}puts("-1");return 0;
}

【CF1182D】Complete Mirror【树的重心】相关推荐

  1. 模板 - 树上问题(树的直径、动态查询树的直径、树的重心)

    整理的算法模板合集: ACM模板 目录 一.树的直径 树形DP 两次DFS / BFS(找到直径的两个端点) 二.动态修改树的边权并求每个时刻的直径(线段树) 三.树的重心 一.树的直径 树的直径满足 ...

  2. 【树形DP】树的重心详解+多组例题详解

    目录 定义: 性质: 算法分析: POJ 1655 Balancing Act(求重心) POJ 3107 Godfather P1364 医院设置(树形DP) 定义: 树的重心也叫树的质心.对于一棵 ...

  3. 树形dp——树的重心(2) 代码调试理解

    和树的最大独立问题类似,先任选一个结点作为根节点,把无根树变成有根树,然后设d(i)表示以i为根的子树的结点的个数.不难发现d(i)=∑d(j)+1,j∈s(i).s(i)为i结点的所有儿子结点的编号 ...

  4. POJ-1655 Balancing Act 树的重心

    题意:完全符合树的重心:即找到一个点,其所有的子树中最大的子树节点最少. 代码如下: #include <cstdlib> #include <cstring> #includ ...

  5. 幽暗统领 树的重心 牛客白月赛44

    链接:https://ac.nowcoder.com/acm/contest/11221/F 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52 ...

  6. POJ 1655 Balancing Act[树的重心/树形dp]

    Balancing Act 时限:1000ms Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered ...

  7. POJ 1655 Balancing Act (树的重心)

    题目链接:http://poj.org/problem?id=1655 题意: 求树的重心(最小序号),以及去掉重心后子树节点最大是多少.(树的重心定义为:找到一个点,其所有的子树中最大的子树节点数最 ...

  8. POJ - 4045 Power Station(树形dp/树的重心)

    题目链接:点击查看 题目大意:给出一个n个节点的树,我们需要选出一个节点,到其余任何节点的距离和最小 题目分析:这个题我的第一反应是用树的重心,先求出来符合条件的点,然后再跑一遍dfs求距离,最后输出 ...

  9. POJ - 1655 Balancing Act(树的重心)

    题目链接:点击查看 题目大意:给一个树,删除其中一个点就会形成一个森林,点的平衡度为删除了这个节点后,所形成多个树,其中组成树的节点最多,节点个数就是那个平衡度. 题目分析:求树的重心,模板题: 树的 ...

最新文章

  1. IC/FPGA大疆笔试题分析(预分析)
  2. 马斯克又破纪录了:120米史上最高火箭已组装,计划今年完成首次轨道试飞
  3. VS2017调试时如何查看内存
  4. day28 socket网络编程
  5. c# list集合根据某个字段去重_Python list、dataframe去重
  6. BEGINNING SHAREPOINT#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 client对象模型(CSOM)基础...
  7. nginx+lua_nginx+GraphicsMagick生成实时缩略图
  8. 嵌入式成长轨迹36 【Zigbee项目】【单片机基础】【单片机SD卡】
  9. 射影几何----齐次坐标下的三点共线和非齐次坐标下的三点共线是等价的
  10. sudo: /etc/sudoers is world writable sudo: no valid sudoers sources found, quitting sudo: 解决方法
  11. 写好一份数据分析报告需要注意的13个要点
  12. 沧小海笔记之PCIE协议解析——第三章 PCIE的数据链路层
  13. php 获取数组长度
  14. 如何用HTML5开发一款手机游戏
  15. Java自学笔记(随时查看)
  16. 从新手到架构师,一篇就够:从100到1000万高并发的架构演进之路
  17. 如何使用使用 HAVING 与 ORDER BY?
  18. 直击JDD | 陈生强:京东数科的底层是数字化操作系统
  19. OSI与TCP/IP协议簇、数据链路层
  20. Cause: java.sql.SQLException: connection closed问题排查、解决

热门文章

  1. 超形象!著名的三角不等式演示动图!
  2. 得罪前女友到底有多可怕?
  3. 又一大波机械动图来了,工作原理都能看明白!
  4. 一组动图看懂3D打印原理
  5. 编程到底难在哪里? 从一个美国实习生的故事说起
  6. java map 值排序_使用Java8 Stream API对Map类型按照键或值进行排序
  7. 为什么年龄大了近视还增加_年龄明明一样大,为什么有人长得年轻,有人显老呢?...
  8. 大数据、java、python、区块链、人工智能哪个发展前景更好?
  9. mysql group 条件,mysql - mysql group by,两个条件,限制1 - SO中文参考 - www.soinside.com...
  10. java实现权限_Java实现常用权限控制算法