zoukankan      html  css  js  c++  java
  • 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
    ",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;
    }

  • 相关阅读:
    Git 安装部署的详细说明
    jmeter数据库连接异常记录
    安装测试真的有那么简单吗?
    5G通信系统简单介绍
    postman 模拟服务器server
    再来对http协议做个详细认识
    关于Fiddler Everywhere的使用说明
    pom模式+ddt思想+logger+allure 重构jpress
    adb常见异常归类
    DDT思想
  • 原文地址:https://www.cnblogs.com/tclan126/p/8480251.html
Copyright © 2011-2022 走看看