hdu 3887 Counting Offspring
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3887
题意:给出一棵树,对于每一个节点,问他的子孙节点中有多少个节点小于该节点。
思路:首先找出这棵树的DFS序列,每一个节点出现在两个位置,这两个位置之间的节点就是该节点的子孙节点。
然后用树状数组求出这两个位置之间有多少个节点小于该节点。
hdu这题出的有点龊 ,,用dfs搜索会爆栈,要手动模拟先序或者后序遍历!
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相关推荐
- hdu 3887 Counting Offspring
题目大意:给你一棵树,求每个父节点的子树中序号小于父节点序号的节点个数. #include <set> #include <map> #include <queue> ...
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- 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 ...
- HDU 2431 Counting Problem
题意: 问 n * n 的格子里面放 2*n个皇后的放法数,满足每行每列的皇后数都是2. 分析: 解法可以由前面的递推到后面,知道 2 * 2 的图有一种情况后,可知大于 2 * 2 的图都可以预留 ...
- HDU - 6184 Counting Stars(思维+三元环)
题目链接:点击查看 题目大意:给出一个 nnn 个点 mmm 条边组成的无向图,问图中有多少个"三元环对","三元环对"指的是两个三元环共用了一条边 题目分析: ...
- HDU 5952 Counting Cliques(2016ACM/ICPC亚洲区沈阳站-重现赛)
题目分析 这道题看样子没有什么办法,主要就是有策略的暴力,因为每个点连接的点不超过20个,那么就可以直接进行暴力,但是这样会有很多重复,因此需要剪枝,具体情况就是每次搜过一个点之后就把这个点连接的所有 ...
- HDU 2952 Counting Sheep (DFS找联通块)
题目链接:请戳这里. 题目大意及思路:读懂题意就好了,就是DFS找联通块. 没什么好说的,见代码吧. #include<cstdio> #include<cstring> ...
- 动态规划总结与题目分类
源博客链接:http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少 ...
- dp进阶之FFT加速+数据结构优化+不等式优化
快速傅里叶变换 快速傅里叶变换(英语:Fast Fourier Transform, FFT),是快速计算序列的离散傅里叶变换(DFT)或其逆变换的方法.傅里叶分析将信号从原始域(通常是时间或空间)转 ...
最新文章
- 【Qt】Qt再学习(七):QLocalServer、QLocalSocket
- SOA:A note on RPC
- VS2008 快捷键大全
- python 找到目录下文件名规则_假如编程是魔法之零基础看得懂的Python入门教程 ——(二)魔法实习生第一步了解魔杖的使用...
- html5与css3都要学吗,前端要学css3吗?
- jQuery 插件格式 规范
- 强烈推荐,关于5G最深刻的一篇文!
- 关于TP中的M()方法与D()方法
- php页面怎么改造mip,WordPress MIP 改造之 a 标签替换为 mip-link 跳转链接
- C实现NV12转I420
- 基于python+qt5考研倒计时器
- 可视化学习:可视化布局方法简介及优缺点
- U盘和移动硬盘不能安全删除问题及解决方案
- Python列表解析式
- 《30天自制操作系统》学习笔记--第12天
- 程序员代码面试指南第二版 4.猫狗队列
- GO 常见环境变量与常用命令
- The LeVoice Far-field Speech Recognition System for VOiCES from a Distance Challenge 2019
- 46. 孩子们的游戏-圆圈中最后剩下的数字
- 软件测试工程师发展方向,主要有哪些?