A family hierarchy is usually presented by a pedigree tree. Your job is to count those family members who have no child.
Each input file contains one test case. Each case starts with a line containing 0
where ID is a two-digit number representing a given non-leaf node, K is the number of its children, followed by a sequence of two-digit ID’s of its children. For the sake of simplicity, let us fix the root ID to be 01.
The input ends with N being 0. That case must NOT be processed.
For each test case, you are supposed to count those family members who have no child for every seniority level starting from the root. The numbers must be printed in a line, separated by a space, and there must be no extra space at the end of each line.
The sample case represents a tree with only 2 nodes, where 01 is the root and 02 is its only child. Hence on the root 01 level, there is 0 leaf node; and on the next level, there is 1 leaf node. Then we should output 0 1 in a line.
2 1
01 1 02
0 1
#include
#include
struct Node
{
int father;
int level;
bool NoChild;
};
Node v[100]; //用以记录树的信息
char level[100] = "\0"; //用以记录树每层叶子节点数
int main()
{
int N, M, c, ID, child, MAXLevel = 1;
scanf_s("%d%d", &N, &M);
//初始化
for (int i = 0; i<100; ++i)
{
v[i].father = 0;
v[i].level = 0;
v[i].NoChild = 1;
}
//获取输入第2行到第M行的信息
for (int i = 0; i<M; ++i)
{
scanf_s("%d%d", &ID, &c);
v[ID].NoChild = 0;
for (int j = 0; j<c; ++j)
{
scanf_s("%d", &child);
v[child].father = ID;
}
}
v[1].level = 1; //根节点层数初始化为1
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j)
{
//如果一个节点的父节点是i
if (v[j].father == i)
{
v[j].level = v[i].level + 1;//那么他的层数等于父节点层数+1
if (v[j].level>MAXLevel)
MAXLevel = v[j].level; //维护一个MAXLevel记录最大层数
}
}
for (int i = 1; i <= N; ++i) //统计每一层的叶子节点数
if (v[i].NoChild == 1)
level[v[i].level]++;
//输出
for (int i = 1; i<MAXLevel; ++i)
printf("%d ", level[i]);
printf("%d\n", level[MAXLevel]);
return 0;
}
算法来自于这篇博客https://blog.csdn.net/qq278672818/article/details/54915636只对它的代码做了一点小改动和加了注释,感谢博主的分享。本来是准备建一棵树然后用广度优先搜索去做的,但是在测试点1和3上出现段错误,后来考虑到输入的过程可能是乱序的,比如考虑构建如下一棵树:
输入为
7 4
01 1 02
02 3 03 04 05
05 1 06
06 1 07
这样顺序输入就是对的,不会段错误。
但是输入为
7 4
01 1 02
05 1 06
02 3 03 04 05
06 1 07
因为处理05 1 06时找不到05号节点而产生段错误
于是我对代码做了调整,在找不到父亲节点时就新建一棵以这个节点为根的树,加入trees的list,而且每次建子节点之前遍历这个list看看是否有根节点ID与子节点ID相同的,如果有就把这两棵树连起来,但只对了测试点3,测试点1还是段错误,不知道哪里还有问题。。
这是原始代码,错测试点1和3。
#include
#include
#include
#include
using namespace std;
struct Node
{
string id;
int level;
vector<Node*> children;
Node(string id, int level);
void getChild(string id, int plevel);
};
struct Tree
{
Node* root;
Node* find(string id);
Tree();
map<int, int> count();
};
Tree::Tree()
{
root = new Node("01", 0);
}
Node* Tree::find(string id)
{
queue<Node*> nodeQueue;
nodeQueue.push(root);
while (!nodeQueue.empty())
{
Node* node = nodeQueue.front();
nodeQueue.pop();
if (node->id == id)
return node;
else
{
for (size_t i = 0; i < node->children.size(); i++)
{
nodeQueue.push(node->children[i]);
}
}
}
return nullptr;
}
map<int, int> Tree::count()
{
map<int, int> countMap; //
queue<Node*> nodeQueue;
nodeQueue.push(root);
while (!nodeQueue.empty())
{
Node* node = nodeQueue.front();
nodeQueue.pop();
if (!countMap.count(node->level))
countMap[node->level] = 0;
if (node->children.size() == 0)
countMap[node->level]++;
for (size_t i = 0; i < node->children.size(); i++)
{
nodeQueue.push(node->children[i]);
}
}
return countMap;
}
Node::Node(string id, int level)
{
this->id = id;
this->level = level;
}
void Node::getChild(string id, int plevel)
{
Node* childNode = new Node(id, plevel + 1);
children.push_back(childNode);
}
int main()
{
int numOfNode;
for (; cin >> numOfNode; )
{
if (!numOfNode) break;
Tree tree;
int numOfNonLeaf;
cin >> numOfNonLeaf;
for (size_t i = 0; i < numOfNonLeaf; i++)
{
string pid;
int k; // num of children
cin >> pid >> k;
Node* pNode = tree.find(pid);
for (int j = 0; j < k; j++)
{
string cid;
cin >> cid;
pNode->getChild(cid, pNode->level);
}
}
map<int, int> countMap = tree.count();
cout << countMap.begin()->second;
map<int, int>::iterator it = countMap.begin();
it++;
for (; it != countMap.end(); it++)
cout << " " << it->second;
cout << endl;
}
return 0;
}
这是修改版代码错测试点1
#include
#include
#include
#include
#include
using namespace std;
struct Node
{
string id;
int level;
vector<Node*> children;
Node(string id, int level);
void getChild(string id, int plevel);
};
struct Tree
{
Node* root;
Node* find(string id);
Tree();
Tree(string id);
map<int, int> count();
void updateLevel();
};
Tree::Tree()
{
root = new Node("01", 0);
}
Tree::Tree(string id)
{
root = new Node(id, 0);
}
Node* Tree::find(string id)
{
queue<Node*> nodeQueue;
nodeQueue.push(root);
while (!nodeQueue.empty())
{
Node* node = nodeQueue.front();
nodeQueue.pop();
if (node->id == id)
return node;
else
{
for (size_t i = 0; i < node->children.size(); i++)
{
nodeQueue.push(node->children[i]);
}
}
}
return nullptr;
}
map<int, int> Tree::count()
{
map<int, int> countMap; //
queue<Node*> nodeQueue;
nodeQueue.push(root);
while (!nodeQueue.empty())
{
Node* node = nodeQueue.front();
nodeQueue.pop();
if (!countMap.count(node->level))
countMap[node->level] = 0;
if (node->children.size() == 0)
countMap[node->level]++;
for (size_t i = 0; i < node->children.size(); i++)
{
nodeQueue.push(node->children[i]);
}
}
return countMap;
}
void Tree::updateLevel()
{
queue<Node*> nodeQueue;
nodeQueue.push(root);
while (!nodeQueue.empty())
{
Node* node = nodeQueue.front();
nodeQueue.pop();
for (size_t i = 0; i < node->children.size(); i++)
{
node->children[i]->level = node->level + 1;
nodeQueue.push(node->children[i]);
}
}
return;
}
Node::Node(string id, int level)
{
this->id = id;
this->level = level;
}
void Node::getChild(string id, int plevel)
{
Node* childNode = new Node(id, plevel + 1);
children.push_back(childNode);
}
int main()
{
int numOfNode;
for (; cin >> numOfNode; )
{
if (!numOfNode) break;
list<Tree> trees;
int numOfNonLeaf;
cin >> numOfNonLeaf;
for (size_t i = 0; i < numOfNonLeaf; i++)
{
string pid;
int k; // num of children
cin >> pid >> k;
Node* pNode = nullptr;
for (auto it : trees)
{
pNode = it.find(pid);
if (pNode != nullptr) break;
}
if (pNode == nullptr)
{
Tree tree(pid);
trees.push_back(tree);
pNode = tree.root;
for (int j = 0; j < k; j++)
{
string cid;
cin >> cid;
Node* cNode = nullptr;
list<Tree>::iterator it = trees.begin();
for (; it != trees.end(); it++)
{
if (it->root->id == cid)
{
cNode = it->root;
trees.erase(it);
break;
}
}
if (cNode != nullptr)
{
pNode->children.push_back(cNode);
}
else
{
pNode->getChild(cid, pNode->level);
}
}
}
else
{
for (int j = 0; j < k; j++)
{
string cid;
cin >> cid;
Node* cNode = nullptr;
list<Tree>::iterator it = trees.begin();
for (; it != trees.end(); it++)
{
if (it->root->id == cid)
{
cNode = it->root;
trees.erase(it);
break;
}
}
if (cNode != nullptr)
{
pNode->children.push_back(cNode);
}
else
{
pNode->getChild(cid, pNode->level);
}
}
}
}
trees.begin()->updateLevel();
map<int, int> countMap = trees.begin()->count();
cout << countMap.begin()->second;
map<int, int>::iterator it = countMap.begin();
it++;
for (; it != countMap.end(); it++)
cout << " " << it->second;
cout << endl;
}
return 0;
}
以上