题目描述在5302长有一棵神奇的树树上结的果子是西瓜。该树为有根树具有n个节点根节点编号为1。树上有且仅有一个节点会结出西瓜果实该节点编号为x。夏天到了王婷好学姐想吃西瓜了学姐每摇一次西瓜树就会发生以下事件若西瓜所在的节点有子节点那么西瓜会随机掉落到它的某一个子节点上。若西瓜所在的节点没有子节点即所在节点为叶节点那么西瓜从该节点上落到地上。显然在有限次的摇动之后西瓜最后会从某一个叶节点落到地上我们
思路:
- 根据输入的边信息,构建一个有根树的邻接表表示。
- 从根节点开始进行深度优先搜索(DFS),统计叶节点的个数。
- 若目标节点x为叶节点,则所有叶节点都是good节点,统计叶节点个数即为结果。
- 若目标节点x不是叶节点,则除了目标节点x以外的所有叶节点都是good节点,统计叶节点个数减1即为结果。
时间复杂度分析: 构建邻接表的时间复杂度为O(n),DFS的时间复杂度为O(n),总时间复杂度为O(n)。
空间复杂度分析: 邻接表的空间复杂度为O(n),递归调用栈的最大深度为树的高度,最坏情况下为O(n),总空间复杂度为O(n)。
代码实现如下:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>> adj;
vector<bool> visited;
int leafCount = 0;
void dfs(int node) {
visited[node] = true;
bool isLeaf = true;
for (int neighbor : adj[node]) {
if (!visited[neighbor]) {
dfs(neighbor);
isLeaf = false;
}
}
if (isLeaf) {
leafCount++;
}
}
int main() {
int n, x;
cin >> n >> x;
adj.resize(n + 1);
visited.resize(n + 1, false);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(1);
if (adj[x].size() == 1 || leafCount == 1) {
cout << leafCount << endl;
} else {
cout << leafCount - 1 << endl;
}
return 0;
}
``
原文地址: https://www.cveoy.top/t/topic/hDxj 著作权归作者所有。请勿转载和采集!