考研机试:统计节点个数

版权声明:本博全为博主学习日常,均为原创,请勿转载 https://blog.csdn.net/weixin_44332298/article/details/87967099

时间限制:1000ms 内存限制:65536KB

题目描述

给出一棵有向树,一共N(1 < N <= 1000)个节点,如果一个节点的度(入度+出度)不小于它所有儿子以及它父亲的度(如果存在父亲或儿子),则称这样的节点为p节点,现要求统计p节点的个数。

输入要求

第一行为数据组数T(1 <= T <= 100)
每组数据第一行为N表示树的节点数,后面为N-1行,每行两个数x,y(0 <= x,y <= N),代表y是x的儿子节点。

输出要求

每组数据输出一行,为一个整数,代表这棵树上p节点的个数。

输入样例

2
5
0 1
1 2
2 3
3 4
3
0 2
0 1

输出样例

3
1

题目分析

1、题目要求计算的度为入度和出度的和,度是图中的概念,用邻接矩阵计算最为方便。且又因为在该题中箭头的方向不是关键(因为是入度+出度),可以直接将有向树转换为无向图,将度看作是权值,这个问题又可以看作“最小堆”问题。只需在最小堆问题的基础上考虑上父节点的度即可。
2、先假设所有的节点都是p节点,一旦判断不符合p节点的条件就减一并跳出循环。

代码

/*
因为度是入度和出度的和,度是在图中的定义,用邻接矩阵计算度最为方便
将有向树转换为无向图用邻接矩阵存储,矩阵的行元素相加即为度。
问题可转化为最小堆问题,将度看作权值,再考虑上父节点即可。
*/
#include <iostream>
#include <string.h>
using namespace std;

int t[1005][1005];//邻接矩阵
int du[1005];//度

int main(){
    int T, N, f, s, temp, count;
    cin >> T;
    while(T--){
        cin >> N;
        memset(t, 0, sizeof(t));
        memset(du, 0, sizeof(du));
        for(int i = 0; i < N-1; i++){//转换成无向图来存储
            cin >> f >> s;
            t[f][s] = 1;
            t[s][f] = 1;
            du[f]++;//入度和出度都需要更新
            du[s]++;
        }
        count = N;//假设所有结点都是p结点
        for(int i = 0; i < N; i++){//按列遍历
            temp = du[i];
            for(int j = 0; j < N; j++){
                if(t[i][j]){
                    if(du[j] > du[i]){
                        count--;
                        break;
                    }
                }
            }
        }
        cout << count << endl;
    }
    return 0;
}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44332298/article/details/87967099