Acwing---846. 树的重心

2024-02-17 12:36
文章标签 acwing 重心 846

本文主要是介绍Acwing---846. 树的重心,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

树的重心

  • 1.题目
  • 2.基本思想
  • 3.代码实现

1.题目

给定一颗树,树中包含 n n n 个结点(编号 1 ∼ n 1∼n 1n)和 n − 1 n−1 n1 条无向边。

请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。

重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。

输入格式
第一行包含整数 n n n,表示树的结点数。

接下来 n − 1 n−1 n1 行,每行包含两个整数 a a a b b b,表示点 a a a 和点 b b b 之间存在一条边。

输出格式
输出一个整数 m,表示将重心删除后,剩余各个连通块中点数的最大值

数据范围
1 ≤ n ≤ 1 0 5 1≤n≤10^5 1n105

输入样例:

9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6

输出样例:

4

2.基本思想

>BFS
(数组建立邻接表) 树的dfs

//邻接表
int h[N], e[N * 2], ne[N * 2], idx;void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

树的bfs模板

// 需要标记数组st[N],  遍历节点的每个相邻的便
void dfs(int u) {st[u] = true; // 标记一下,记录为已经被搜索过了,下面进行搜索过程for (int i = h[u]; i != -1; i = ne[i]) {int j = e[i];if (!st[j]) {dfs(j);}}
}
  • 本题的本质是树的dfs, 每次dfs可以确定以u为重心的最大连通块的节点数,并且更新一下ans。

也就是说,dfs并不直接返回答案,而是在每次更新中迭代一次答案。

  • 在本题的邻接表存储结构中,有两个容易混淆的地方,一个是节点的编号,一个是节点的下标。
    节点的编号是指上图所画的树中节点的值,范围是从1~n。在本题中,每次输入的a和b就是节点的编号,编号用e[i]数组存储。
    节点的下标指节点在数组中的位置索引,数组之间的关系就是通过下标来建立连接,下标用idx来记录。idx范围从0开始,如果idx==-1表示空。
    e[i]的值是编号,是下标为i节点的编号。
    ne[i]的值是下标,是下标为i的节点的next节点的下标。
    h[i]存储的是下标,是编号为i的节点的next节点的下标,比如编号为1的节点的下一个节点是4,那么我输出e[h[1]]就是4

3.代码实现


import java.util.Scanner;public class Main {static int N = 100010;static boolean st[] = new boolean[N];static int[] h = new int[N], e = new int[N*2], ne = new int[N*2];static int n, idx, ans = N;static void init() {for (int i = 0; i < N; i++) h[i] = -1;}static private void add(int a, int b) {e[idx] = b;ne[idx] = h[a];h[a] = idx++;}//返回以 u 为根的子树的点的数量private static int dfs(int u) {st[u] = true;int sum = 1, res = 0;// res:删除根后 每个连通块的最大值for (int i = h[u]; i != -1; i = ne[i]) {int j = e[i];if (!st[j] ) {int s = dfs(j);//当前子树大小res = Math.max(res, s);sum += s;}}res = Math.max(res, n - sum);ans=Math.min(ans,res);return sum;}public static void main(String[] args) {init();Scanner sc = new Scanner(System.in);n = sc.nextInt();for (int i = 0; i < n-1; i++) {int a = sc.nextInt(), b = sc.nextInt();add(a, b);add(b, a);}dfs(1);System.out.println(ans);}
}

这篇关于Acwing---846. 树的重心的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717774

相关文章

【AcWing】851. 求最短路

spfa算法其实是对贝尔曼福特算法做一个优化。 贝尔曼福特算法会遍历所有边来更新,但是每一次迭代的话我不一定每条边都会更新,SPFA是对这个做优化。 如果说dist[b]在当前这次迭代想变小的话,那么一定是dist[a]变小了,只有a变小了,a的后继(b)才会变小。 用宽搜来做优化,用一个队列,队列里边存的就是所有变小了的结点(队列里存的是待更新的点)。 基本思路就是我更新过谁,我再拿

【AcWing】852. spfa判断负环

#include<iostream>#include<algorithm>#include<cstring>#include<queue>using namespace std;const int N= 1e5+10;int n,m;int h[N],w[N],e[N],ne[N],idx;int dist[N],cnt[N];//cnt存最短路径的边数bool st[N];v

leetcode解题思路分析(九十八)846 - 852 题

一手顺子 爱丽丝有一手(hand)由整数数组给定的牌。 现在她想把牌重新排列成组,使得每个组的大小都是 W,且由 W 张连续的牌组成。如果她可以完成分组就返回 true,否则返回 false。 记录每个牌是否用过,排序后依次找即可 class Solution {public:bool isNStraightHand(vector<int>& hand, int groupSize) {in

AcWing 282. 石子合并

必看的视频讲解↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【E28【模板】区间DP 石子合并——信息学竞赛算法】 合并过程总开销等于红色数字总和,可以理解为花费的总体力! f数组的含义是f【i】【j】是从第i堆石子开始到第j堆石子的花费体力最小值 如何理解三层for呢? 第一层for是控制区间长度len,第二层for是控制区间起点位置i,第三层for是控制区间

AcWing 897. 最长公共子序列

动态规划就是多见识应用题就完事儿了,也没有什么好说的。 讲解参考: 【E05 线性DP 最长公共子序列】 #include<iostream>#include<algorithm>#define N 1010using namespace std;char a[N],b[N];int n,m;int f[N][N];int main(){cin >> n >> m >> a

AcWing 2. 01背包问题

一定要看的视频讲解:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【E08【模板】背包DP 01背包——信息学竞赛算法】 i表示放入i个物品,j表示第j个物品,用于访问体积v【j】 #include <iostream>#include <algorithm>using namespace std;const int N = 1010;int n, m;int v[N]

AcWing-算法提高课(第一章)-下

区间DP 环形石子合并 状态表示:f[i,j](f[i,j]表示,在,由,将第i堆石子到第j堆石子合并成一堆石子的每个合并方式的代价,组成的集合,中,的最小值)状态计算:f[i,j]=min(f[i,k]+f[k+1,j]+s[j]-s[i-1])(s[j]表示第1堆石子到第j堆石子的总重量,s[i-1]表示第1堆石子到第i-1堆石子的总重量,s[j]-s[i-1]表示第i堆石子到第j堆石子的

贪心推公式——AcWing 125. 耍杂技的牛

贪心推公式 定义 贪心算法是一种在每一步选择中都采取在当前状态下最优的选择,希望通过局部的最优选择来得到全局最优解的算法策略。 运用情况 问题具有最优子结构,即一个问题的最优解包含其子问题的最优解。可以通过局部最优决策逐步推导到全局最优。问题的选择策略相对明确且易于计算。 注意事项 贪心算法并不总是能得到全局最优解,可能会陷入局部最优。对于一些复杂问题,需要谨慎验证其正确性。可能需要对

栅格数据重心迁移变化分析

目前网络上大多是针对矢量重心迁移进行计算,或把栅格转矢量在进行计算,可以不用怎么麻烦,可以直接利用栅格进行得出多期数据的重心,然后进行变化分析等方面的分析。 矢量数据可以通过下面方式进行重心计算: 使用ArcGIS空间统计工具箱(Spatial Statistics Tools)中的平均中心(Mean Center) 对于栅格数据:利用如下公式: 其实就是加权公式,上述w是像元i处的像元值,(x

状态压缩DP——AcWing 291. 蒙德里安的梦想

状态压缩DP 定义 状态压缩DP是一种利用二进制数来表示状态的动态规划算法。它通过将状态压缩成一个整数,从而减少状态数量,提高算法效率。 运用情况 状态压缩DP通常用于解决具有状态转移和最优解性质的问题,例如组合优化、图论、游戏等问题。它的基本思想是将问题的状态表示为一个二进制数,其中每一位表示一个元素或一个状态。通过对二进制数的位运算,可以方便地进行状态转移和最优解的计算。 注意事项