1004. Counting Leaves (30)
Input
Each input file contains one test case. Each case starts with a line containing 0 < N < 100, the number of nodes in a tree, and M (< N), the number of non-leaf nodes. Then M lines follow, each in the format:
ID K ID[1] ID[2] ... ID[K]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.
Output
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.
Sample Input2 1 01 1 02Sample Output
0 1
1,、DFS:深度遍历是一个分支一个分支的访问,一个分支结束的标志是叶子节点。层次数level是在变化的,所以要把最大的Level赋值给maxlayer。这种方法好像可以求树的深度。(重点理解和看)
#include<iostream>
#include<vector>
using namespace std;
const int maxsize=102;
int layer[maxsize];//统计每层的叶子节点个数
vector<int>node[maxsize];
int maxlayer=0;
int n,m;
void dfs(int u,int level)
{
int k=node[u].size();
if(k==0)
{
layer[level]++;
if(level>maxlayer)//重要
maxlayer=level;
return ;
}
for(int i=0;i<node[u].size();++i)
dfs(node[u][i],level+1);
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>n>>m;
for(int i=0;i<m;++i)
{
int non_leaf,k,leaf;
cin>>non_leaf>>k;
for(int j=0;j<k;++j)
{
cin>>leaf;
node[non_leaf].push_back(leaf);
}
}
dfs(1,0);
cout<<layer[0];
for(int i=1;i<=maxlayer;++i)
cout<<" "<<layer[i];
return 0;
}
1.1、这个贴上去知识长见识的
#include <iostream>
#include <map>
#include <vector>
using namespace std;
map<int,vector<int> > adjlist;
int levelleaves[105]={0};
void dfs(int node,int level){
if(adjlist[node].empty()){
levelleaves[level]++;
return;
}
vector<int>:: iterator itea = adjlist[node].begin();
for(;itea!=adjlist[node].end();itea++){
dfs(*itea,level+1);
}
}
int main()
{
int n,m;
cin>>n>>m;
int leaves = n-m;
for(int i=0;i<m;i++){
int id1,k, id2;
cin>>id1>>k;
for(int j=0;j<k;j++){
cin>>id2;
adjlist[id1].push_back(id2);
}
}
dfs(1,0);
int a=levelleaves[0];
cout<<levelleaves[0];
for(int i=1;a<leaves;i++){
cout<<" "<<levelleaves[i];
a=a+levelleaves[i];
}
return 0;
}
2、BFS:自己写的折腾了半天,原来还是没有集中注意力,还是要细心。每次队列进一层的节点,然后再一层一层的遍历访问。 (重点理解和看)感觉bfs我写的有点冗余,等我熟练或者哪位大神可以提提意见
#include<iostream>
#include<vector>
using namespace std;
const int maxsize=101;
vector<int>node[maxsize];//保存非叶子节点以及对应的孩子节点
int layer[maxsize];
int level=0;//记录层次数
int preleaf=1;//保存本层出队列节点个数
int nextleaf=0;//保存要出队列的孩子节点的个数
int n,m;
void bfs(int u)
{
int que[maxsize];//保存每层的节点的循环队列
int front=0;
int rear=0;
que[(++rear)%maxsize]=u;//根节点入队列
while(front!=rear)//全部访问完时结束
{
while(preleaf--!=0)//遍历判断本层节点
{
int next=que[(++front)%maxsize];//出队
if(node[next].size()==0)
layer[level]++;//之前错写成layer[level++]++
nextleaf+=node[next].size();
for(int i=0;i<node[next].size();++i)
que[(++rear)%maxsize]=node[next][i];//进队
}
if(front!=rear)
level++;
preleaf=0;
while(nextleaf--!=0)//遍历判断上层节点的孩子节点
{
int next=que[(++front)%maxsize];//出队
if(node[next].size()==0)
layer[level]++;
preleaf+=node[next].size();
for(int i=0;i<node[next].size();++i)
que[(++rear)%maxsize]=node[next][i];//进队
}
if(front!=rear)//防止在前一层结束使level多加了
level++;
nextleaf=0;
}
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>n>>m;
for(int i=0;i<m;++i)
{
int non_leaf,k,leaf;
cin>>non_leaf>>k;
for(int j=0;j<k;++j)
{
cin>>leaf;
node[non_leaf].push_back(leaf);
}
}
bfs(1);
cout<<layer[0];
for(int i=1;i<=level;++i)
cout<<" "<<layer[i];
return 0;
}
2.1别人的bfs看的贼费劲,先粘贴一下,自己有时间再看吧
#include <iostream>
#include <vector>
#include <queue>
int n, m;
std::vector<std::vector<int>> edge;
std::vector<int> BFS(int s)
{
std::queue<std::pair<int,int>> q;
q.push(std::make_pair(s, 0));
int cur_step = 0;
std::vector<int> ans;
int cnt = 0;
while (!q.empty())
{
int u = q.front().first;
int step = q.front().second;
q.pop();
if(step > cur_step)
{
ans.push_back(cnt);
cnt = 0;
cur_step = step;
}
if(edge[u].size() == 0) cnt++;
for (int i = 0; i < edge[u].size(); ++i)
{
int v = edge[u][i];
q.push(std::make_pair(v, step+1));
}
}
ans.push_back(cnt);
return ans;
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
//input edges
edge.clear();
edge.resize(n+1);
while (m--)
{
int a, k;
scanf("%d%d", &a,&k);
while (k--)
{
int b;
scanf("%d",&b);
edge[a].push_back(b);
//edge[b].push_back(a);
}
}
std::vector<int> ans = BFS(1);
//output
for (int i = 0; i < ans.size(); ++i)
{
if(i != ans.size()-1)
printf("%d ", ans[i]);
else printf("%d\n", ans[i]);
}
}
return 0;
}