帮我做题K 有一无向连通图 GG(nn 个顶点,n - 1n−1 条边,点从 11 到 nn 依次编号)。当然,你能看出这其实就是一棵树,请找出所有满足以下条件的节点: 该节点不是叶子节点(度不为 00)。 该节点下面所有的子树大小必须相同(如果下面只有一棵子树也默认为相同)。 注意,该树为有根树,你需要先找到它的根才能开始访问其他节点。 请你设计程序,完成上面要求。 输入格式 第一行包含 11 个整数 nn。 接下来 n-1n−1 行,每行包含 22 个用空格隔开的正整数 uu、vv,表示编号为 uu 和编号为 vv 的点之间有边相连,其中 uu 是 vv 的父亲节点。 输出格式 输出共 11 行,包含若干个整数,之间用空格隔开,表示为满足题目要求的节点编号。 注意,输出的顺序要按照编号 从小到大 进行输出。 数据范围 对于 3030% 的数据,1< n \le1001<n≤100; 对于 6060% 的数据,1< n \le 20001<n≤2000; 对于 100100% 的数据,1< n \le 200,0001<n≤200,000。
时间: 2023-02-06 17:31:14 浏览: 209
这道题的主要思路就是求出每个点的子树的大小,然后遍历每个点判断其是否满足条件,如果满足就输出。
因为这是一棵有根树,所以可以先找出根节点。然后可以用深度优先搜索来遍历整棵树,在遍历的过程中就可以求出每个点的子树大小。
算法流程:
1. 找出根节点(没有父亲节点的节点)
2. 从根节点开始,使用深度优先搜索遍历整棵树
3. 在遍历的过程中,对于每个节点,求出其子树的大小
4. 对于每个节点,判断其是否满足条件,如果满足就输出
这里给出一个 C++ 的代码实现:
```
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200005;
int h[N], e[N], ne[N], idx;
int n, root;
int size[N];
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int u)
{
size[u] = 1;
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if (j == root) continue;
dfs(j);
size[u] += size[j];
}
}
int main()
{
cin >> n;
memset(h, -1, sizeof h);
for (int i = 0; i < n - 1; i ++ )
{
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
阅读全文