• Hdu 5326 Work


      可以把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
    ", sum);
        }
        return 0;
    }
    
  • 相关阅读:
    luogu P3174 毛毛虫
    P3386二分图最大匹配模版
    P4180 严格次小生成树
    差分约束
    高斯消元
    P1306 斐波那契公约数
    极值
    排序
    P1852 [国家集训队]跳跳棋
    高精度模版
  • 原文地址:https://www.cnblogs.com/Emerald/p/4700229.html
Copyright © 2020-2023  润新知