题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3887

题意:给出一棵树,对于每一个节点,问他的子孙节点中有多少个节点小于该节点。

思路:首先找出这棵树的DFS序列,每一个节点出现在两个位置,这两个位置之间的节点就是该节点的子孙节点。

然后用树状数组求出这两个位置之间有多少个节点小于该节点。

hdu这题出的有点龊 ,,用dfs搜索会爆栈,要手动模拟先序或者后序遍历!

code:

View Code

  1 # include<stdio.h>  2 # include<string.h>  3 # define N 100050  4 struct node{  5     int from,to,next;  6 }edge[2*N],edge1[2*N];  7 int head[N],tol,head1[N],tol1,S[N],s[N],k,dp[N],count[N],visit[N],sig[N];  8 void add(int a,int b)  9 { 10     edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++; 11 } 12 void add1(int a,int b) 13 { 14     edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++; 15 } 16 void dfs2(int root) 17 { 18     int j,top,u,v; 19     top=0; 20     k=0; 21     S[++top]=root; 22     while(top>0) 23     { 24         u=S[top]; 25         if(!visit[u]) 26         { 27             visit[u]=1; 28             s[++k]=u; 29             sig[u]=k; 30         } 31         for(j=head[u];j!=-1;j=edge[j].next) 32         { 33             v=edge[j].to; 34             if(visit[v]) continue; 35             S[++top]=v;  36             break; 37         } 38         if(j==-1) 39         { 40             top--; 41             dp[u]=k-sig[u]; 42         } 43     } 44 } 45 void insert(int i) 46 { 47     while(i<=k) 48     { 49         count[i]++; 50         i+=i&(-i); 51     } 52 } 53 int query(int i) 54 { 55     int sum=0; 56     while(i>0) 57     { 58         sum+=count[i]; 59         i-=i&(-i); 60     } 61     return sum; 62 } 63 int main() 64 { 65     int i,j,v,n,root,num[N],ans,node,a,b; 66     while(scanf("%d%d",&n,&root)!=EOF) 67     { 68         if(!n && !root) break; 69         tol=0; 70         memset(head,-1,sizeof(head)); 71         for(i=1;i<n;i++) 72         { 73             scanf("%d%d",&a,&b); 74             add(a,b); 75             add(b,a); 76         } 77         memset(dp,0,sizeof(dp)); 78         //dfs1(root,0);//树形DP求节点子孙的个数 79         memset(visit,0,sizeof(visit)); 80         dfs2(root);//模拟栈,先序遍历 81         tol1=0; 82         memset(head1,-1,sizeof(head1)); 83         for(i=1;i<=n;i++) 84         { 85             node=s[i]; 86             ans=dp[node]+i; 87             add1(ans,node); 88         } 89         memset(count,0,sizeof(count)); 90         for(i=1;i<=n;i++) 91         { 92             node=s[i]; 93             num[node]=query(node-1); 94             insert(node); 95             for(j=head1[i];j!=-1;j=edge1[j].next) 96             { 97                 v=edge1[j].to; 98                 num[v]=query(v-1)-num[v]; 99             }100         }101         printf("%d",num[1]);102         for(i=2;i<=n;i++)103             printf(" %d",num[i]);104         printf("\n");105     }106     return 0;107 }

转载于:https://www.cnblogs.com/183zyz/archive/2011/09/30/2196452.html

hdu 3887 Counting Offspring相关推荐

  1. hdu 3887 Counting Offspring

    题目大意:给你一棵树,求每个父节点的子树中序号小于父节点序号的节点个数. #include <set> #include <map> #include <queue> ...

  2. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  3. HDU 3240 Counting Binary Trees 数论-卡特兰数

    题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3240 卡特兰数递推公式h(i)=h(i-1)*(4*i-2)/(i+1) 如果直接算每一步,然后mo ...

  4. HDU 2431 Counting Problem

    题意: 问 n * n 的格子里面放 2*n个皇后的放法数,满足每行每列的皇后数都是2. 分析: 解法可以由前面的递推到后面,知道 2 * 2 的图有一种情况后,可知大于 2 * 2 的图都可以预留 ...

  5. HDU - 6184 Counting Stars(思维+三元环)

    题目链接:点击查看 题目大意:给出一个 nnn 个点 mmm 条边组成的无向图,问图中有多少个"三元环对","三元环对"指的是两个三元环共用了一条边 题目分析: ...

  6. HDU 5952 Counting Cliques(2016ACM/ICPC亚洲区沈阳站-重现赛)

    题目分析 这道题看样子没有什么办法,主要就是有策略的暴力,因为每个点连接的点不超过20个,那么就可以直接进行暴力,但是这样会有很多重复,因此需要剪枝,具体情况就是每次搜过一个点之后就把这个点连接的所有 ...

  7. HDU 2952 Counting Sheep (DFS找联通块)

    题目链接:请戳这里.   题目大意及思路:读懂题意就好了,就是DFS找联通块. 没什么好说的,见代码吧. #include<cstdio> #include<cstring> ...

  8. 动态规划总结与题目分类

    源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...

  9. dp进阶之FFT加速+数据结构优化+不等式优化

    快速傅里叶变换 快速傅里叶变换(英语:Fast Fourier Transform, FFT),是快速计算序列的离散傅里叶变换(DFT)或其逆变换的方法.傅里叶分析将信号从原始域(通常是时间或空间)转 ...

最新文章

  1. 【Qt】Qt再学习(七):QLocalServer、QLocalSocket
  2. SOA:A note on RPC
  3. VS2008 快捷键大全
  4. python 找到目录下文件名规则_假如编程是魔法之零基础看得懂的Python入门教程 ——(二)魔法实习生第一步了解魔杖的使用...
  5. html5与css3都要学吗,前端要学css3吗?
  6. jQuery 插件格式 规范
  7. 强烈推荐,关于5G最深刻的一篇文!
  8. 关于TP中的M()方法与D()方法
  9. php页面怎么改造mip,WordPress MIP 改造之 a 标签替换为 mip-link 跳转链接
  10. C实现NV12转I420
  11. 基于python+qt5考研倒计时器
  12. 可视化学习:可视化布局方法简介及优缺点
  13. U盘和移动硬盘不能安全删除问题及解决方案
  14. Python列表解析式
  15. 《30天自制操作系统》学习笔记--第12天
  16. 程序员代码面试指南第二版 4.猫狗队列
  17. GO 常见环境变量与常用命令
  18. The LeVoice Far-field Speech Recognition System for VOiCES from a Distance Challenge 2019
  19. 46. 孩子们的游戏-圆圈中最后剩下的数字
  20. 软件测试工程师发展方向,主要有哪些?

热门文章

  1. Neural Networks and Deep Learning 读书笔记
  2. Android 动画效果及Interpolator和AnimationListener的使用
  3. Deep Learning(深度学习) 学习笔记(四)
  4. 考研数学:【以错补错】 降低做题出错率
  5. H3C通过端口ID决定端口角色
  6. 【集合工具类:Collections】
  7. tcp/ip知识点的总结
  8. 最近阅读20171106
  9. 汇编 if else
  10. 收藏属于自己flash类库集工具