版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chr1991/article/details/80945436
原题链接:https://www.hackerrank.com/challenges/even-tree/problem
思路:把树还原出来,对每个结点,计算以该结点为根的子树结点数。子树结点数为偶数的结点数量就是所求森林中树木的数量。结点数量减去一就是所求结果。
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int index, num_subtree;
vector<node*> children;
node(int i=0,int n=0):
index(i),num_subtree(n), children(vector<node*>()){}
};
node* construct_tree(int parent, int index, const vector<vector<int>>& adjLsit);
void count_even(node* root, int& cnt);
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int N, M; cin >> N >> M;
vector<vector<int>> adjList(N + 1);
for(int i = 0; i < M; i++){
int n1, n2; cin >> n1 >> n2;
adjList[n1].push_back(n2);
adjList[n2].push_back(n1);
}
node* root = construct_tree(0, 1, adjList);
int cnt = 0;
count_even(root, cnt);
cout << cnt - 1 << endl;
return 0;
}
node* construct_tree(int parent, int index, const vector<vector<int>>& adjList){
node* tmp = new node(index);
tmp->num_subtree = 1;
for(int i = 0; i < adjList[index].size(); i++){
if(adjList[index][i] != parent){
tmp->children.push_back(construct_tree(index, adjList[index][i], adjList));
tmp->num_subtree += tmp->children.back()->num_subtree;
}
}
return tmp;
}
void count_even(node* root, int& cnt){
for(auto vit: root->children){
count_even(vit, cnt);
}
if(root->num_subtree%2==0){
cnt++;
}
}