标签:
可以把N个人分别看作顶点,各种关系则看作边,因为边数正好是N-1,结合题目,其实可以证明这是一棵树。题目要求的就是计算结点数(不包括根)的为K的子树有多少棵。
建立一棵树,然后一个结点 i 为根的子树的结点数,就是 i 的直接相连的结点,以及以它直接相连的结点为根的子树的结点数。如果没有子结点,则放回0。因为有些结点会重复访问,且没必要重新计算,因此可以将其结果保存,避免重复计算。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN = 100 + 50;
std::vector<int> link[MAXN];
int manage[MAXN];
int N, K;
void Init() {
for(int i=1; i<=N; i++) {
link[i].clear();
manage[i] = -1;
// -1 代表此结点尚未被访问
}
}
void Read() {
int x, y;
for(int i=0; i<N-1; i++) {
scanf("%d%d", &x, &y);
link[x].push_back(y);
}
}
int Count(int ser) {
if(manage[ser]!=-1) {
// 已经访问过此结点,直接返回结果即可
return manage[ser];
}
if( link[ser].size() == 0 ) {
// 叶子结点
return manage[ser] = link[ser].size();
} else {
int sum = 0;
for(size_t i = 0; i<link[ser].size(); i++) {
sum += Count(link[ser][i]);
}
return manage[ser] = link[ser].size() + sum;
}
}
int main() {
while(cin >> N >> K) {
Init();
Read();
int sum = 0;
for(int i=1; i<N+1; i++) {
if( Count(i) == K ) {
sum ++;
}
}
printf("%d\n", sum);
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/Emerald/p/4700229.html