DFS秒解一
[YsOI2020] 植树(洛谷)
题目背景
Ysuperman 响应号召,决定在幼儿园里植树。
题目描述
Ysuperman 有一棵
既然树是无根的,那就没有办法种植。Ysuperman 研究了很久的园艺,发现一个节点如果可以成为根,它必须十分平衡,这意味着以它为根时,与它直接相连的节点,他们的子树大小都相同。
你作为幼儿园信息组一把手,Ysuperman 给你一棵树,你能在
输入格式
第一行一个正整数
此后
输出格式
不超过
样例 #1
样例输入 #1
2
1 2
样例输出 #1
1 2
样例 #2
样例输入 #2
4
1 2
2 3
3 4
样例输出 #2
1 4
样例 #3
样例输入 #3
9
1 2
1 3
4 1
5 1
1 6
1 9
8 1
1 7
样例输出 #3
1 2 3 4 5 6 7 8 9
提示
样例说明
样例说明 。
以
以
所以答案为
样例说明
以
以
以
以
所以答案为
数据范围
本题采用捆绑测试。
分数 | ||
---|---|---|
对于
提示
由于输入输出量较大,你可能需要快速输入/输出。
解答
注意
root
数组是判断当前节点是否可以作为根num
是计算当前节点子树大小- 最后在
for
循环外面加加是当前节点也加1
flag
的妙用- 无向图,数组开两倍
#include <iostream>
#include <cstring>
using namespace std;
const int N = 2e6 + 10;
bool st[N];
bool root[N];
int num[N];
int h[N], e[N], ne[N], idx;
int n;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
int dfs(int u)
{
root[u] = 1;
int flag = 0;
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
if (!st[j])
{
st[j] = true;
num[u] += dfs(j);
if (!flag) flag = num[j];
if (flag != num[j]) root[u] = 0;
}
}
num[u]++;
// 这个作用就是判断当前节点作为根节点是否满足
// n - num[u]是另一个分支
// flag是一个分支,相当于是构造了二叉树
// 看题解的图
if (u != 1 && flag && flag != n - num[u]) root[u] = 0;
return num[u];
}
int main()
{
cin >> n;
int n1 = n - 1;
memset(h, -1, sizeof h);
while (n1--)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b), add(b, a);
}
st[1] = true;
dfs(1);
for (int i = 1; i <= n; i++)
if (root[i])
printf("%d ", i);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】