版权声明:本博全为博主学习日常,均为原创,请勿转载 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;
}