1004. Counting Leaves (30)
思路:
(1)bfs
1.
先建树
比如利用 vector<vector<int>> v;
v[node].size() 即为叶子的判别条件
2.
利用bfs逐层判断节点是否为叶子节点,若是则level数组对应的位置加一
3.
求出深度并打印
#include <cstdio> #include <vector> #include <queue> #include <cstring> #include <algorithm> using namespace std; vector<vector<int>> v; int n,m; queue<int> q; int level[100]; int mh=0; void bfs(int l) { while(q.empty() != true) { int newnode=q.front(); //pop并不会返回元素 q.pop(); if(v[newnode].size() == 0) { level[l]++; continue; } for(int i =0;i<v[newnode].size();i++) { q.push(v[newnode][i]); bfs(l+1); } } } int gethigh(int h,int node){ if(v[node].size() == 0) mh=max(h,mh); for(int i =0;i<v[node].size();i++) { gethigh(h+1,v[node][i]); } } int main() { scanf("%d %d",&n,&m); v.resize(n+1); memset(level,0,100); //建树 for(int i=0;i<m;i++) { int id,k; scanf("%d %d",&id,&k); for(int j =0;j<k;j++) { int ch; scanf("%d",&ch); v[id].push_back(ch); } } q.push(1); bfs(0); gethigh(0,1); // printf("mh:%d\n",mh); for(int i=0;i<=mh;i++) { i == 0? printf("%d",level[i]):printf(" %d",level[i]); } return 0; }
(2)dfs
1.建树
2.用dfs搜这棵树并记录最大深度,dfs的参数中有每个节点的深度,保存每个深度的叶子数
3.打印
顺带一提的是要注意memset的第三个参数是指字节,所以只要当第二个参数是-1或0才能达到想要的效果
#include <cstdio> #include <vector> #include <cstring> using namespace std; vector<vector<int>> v; int n,m; int maxl=-1; int leaves[101]; void dfs(int node,int l) { if(v[node].size() == 0) { leaves[l]++; maxl=max(l,maxl); return; } for(int i =0;i<v[node].size();i++) { dfs(v[node][i],l+1); } } int main() { scanf("%d %d",&n,&m); memset(leaves,0,sizeof(leaves)); v.resize(n+1); //建树 for(int i=0;i<m;i++) { int id,k; scanf("%d %d",&id,&k); for(int j=0;j<k;j++) { int val; scanf("%d",&val); v[id].push_back(val); } } //dfs dfs(1,0); for(int i=0;i<=maxl;i++) { i==0? printf("%d",leaves[i]):printf(" %d",leaves[i]); } return 0; }
(3)bfs
可以看到(1)虽然是bfs但是bfs中还用了递归所以写一下不含递归的bfs
#include <cstdio> #include <vector> #include <cstring> #include <queue> using namespace std; vector<vector<int>> v; int n,m; queue<int> q; int mh=-1; int level[101]; int leaves[101]; void bfs() { q.push(1); level[1]=0; while(!q.empty()) { int index=q.front(); mh=max(mh,level[index]); q.pop(); if(v[index].size() == 0) { leaves[level[index]]++; } for(int i =0;i<v[index].size();i++) { q.push(v[index][i]); level[v[index][i]]=level[index]+1; } } } int main() { scanf("%d %d",&n,&m); v.resize(n+1); memset(level,0,sizeof(level)); memset(level,0,sizeof(leaves)); //建树 for(int i=0;i<m;i++) { int id,k; scanf("%d %d",&id,&k); for(int j =0;j<k;j++) { int val; scanf("%d",&val); v[id].push_back(val); } } bfs(); for(int i=0;i<=mh;i++) { i == 0? printf("%d",leaves[i]):printf(" %d",leaves[i]); } return 0; }
(4)bfs 上一种bfs判断一层是通过一个数组level,并通过leaves数组在得到一个节点的层数后进行判断操作,但是也可以通过在每一层压入队列后压入一个标志来
判断是否为一层
#include <cstdio> #include <vector> #include <queue> using namespace std; vector<vector<int>> v; queue<int> q; int bfs(int node) { //判断是不是叶子的标志 int flag=1; for(int i=0;i<v[node].size();i++) { q.push(v[node][i]); flag=0; } return flag; } void ac_bfs(){ q.push(1); //层结束标志 q.push(0); int cnt=0; while(!q.empty()) { int node=q.front(); q.pop(); if(node == 0) { //某一层结束 if(q.empty()) {//最后一层 printf("%d",cnt); return; }else {//不是最后一层 printf("%d ",cnt); q.push(0); cnt=0; } } else { //若flag为1则该层叶子数加一 int flag=bfs(node); cnt+=flag; } } } int main() { int n,m; scanf("%d %d",&n,&m); v.resize(n+1); //建树 for(int i =0;i<m;i++) { int id,k; scanf("%d %d",&id,&k); for(int j=0;j<k;j++) { int val; scanf("%d",&val); v[id].push_back(val); } } ac_bfs(); return 0; }
Yosoro