ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NC15033 小G有一个大树

2022-08-23 12:33:17  阅读:179  来源: 互联网

标签:子树 大树 fa 一个 int NC15033 节点 dp Size


题目链接

题目

题目描述

小G想要把自己家院子里的橘子树搬到家门口(QAQ。。就当小G是大力水手吧)
可是小G是个平衡性灰常灰常差的人,他想找到一个这个橘子树的平衡点。
怎么描述这棵树呢。。。就把它看成由一个个节点构成的树吧。结点数就
代表树重。

输入描述

多组数据输入输出,
第一行包含一个整数n(3<=n<=1000)代表树的结点的个数
以下n-1行描述(1-n)节点间的连接关系。

输出描述

输出两个个整数 x,num 分别代表树的平衡点,和删除平衡点后最大子树的结点数(如果结点数相同输出编号小的)。

示例1

输入

3
1 2
1 3

输出

1 1

题解

知识点:树形dp。

要求的不是整颗树的性质,而是某点相对于树的性质,直接枚举每个点求一次dp复杂度太高,考虑二次扫描与换根法。

先取一个点作为根dp一遍,求出每个点的子树的答案。再从头开始进行dp,假设父节点对于整个树的答案已经求出,可以通过这个答案结合子树答案,推断出子节点对于整棵树的答案。

回到题目上,要求的是节点数。于是取 \(1\) 作为根节点,第一遍dp求出每个节点的子树的节点数 \(Size[u]\) ,转移方程看代码很基础。第二遍dp再从 \(1\) 出发求出节点答案 \(F[u]\)。考虑删除了父节点 \(u\) ,会出现由 \(u\) 的各个子节点 \(v_i\) 对应的子树,以及 \(u\) 向上的一整棵树。于是 \(F[u] = max(n-Size[u],Size[v_i])\) ,表示这些树中最多的节点数即是这个节点的答案。最终取 \(F[u]\) 里最小的,并记录编号即可。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

int n;
vector<int> g[1007];
int Size[1007], F[1007];
int ans, id;

void dfs1(int u, int fa) {
    for (auto v : g[u]) {
        if (fa == v) continue;
        dfs1(v, u);
        Size[u] += Size[v];
    }
    Size[u]++;
}

void dfs2(int u, int fa) {
    F[u] = n - Size[u];
    for (auto v : g[u]) {
        if (v == fa) continue;
        dfs2(v, u);
        F[u] = max(F[u], Size[v]);
    }
    if (ans > F[u]) {
        ans = F[u];
        id = u;
    }
}

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    while (cin >> n) {
        for (int i = 1;i <= n;i++) g[i].clear();
        for (int i = 1;i <= n - 1;i++) {
            int u, v;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        memset(Size, 0, sizeof(Size));
        dfs1(1, 0);
        ans = 1e9;
        dfs2(1, 0);
        cout << id << ' ' << ans << '\n';
    }
    return 0;
}

标签:子树,大树,fa,一个,int,NC15033,节点,dp,Size
来源: https://www.cnblogs.com/BlankYang/p/16615709.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有