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;
}

 

 

posted @ 2018-02-27 18:06  lan126  阅读(142)  评论(0编辑  收藏  举报