HDU5647 Tree DP
2016-03-21 16:33
357 查看
这个题的意思是树的所有连通量的个数之和, 我们定义g[i]为以i为根的子数的个数, f[i]为以i为根的所有连通分量元素个数之和, 那么f[u] = f[u]*(g[v]+1) + f[v]*g[u]; g[u] = g[u]*(g[v]+1); 然后在回溯的时候计算一下即可, 代码如下:
#include <cstdio> #include <cstring> #include <vector> using namespace std; typedef long long LL; const LL m = 1e9+7; vector<int> G[200000 + 100]; int n; LL g[200000+100]; LL f[200000+100]; LL ans; void dfs(int u, int pre){ g[u]=1; f[u]=1; for(int i=0; i<G[u].size(); i++) { int v = G[u][i]; if(v != pre) { dfs(v, u); f[u] = (f[u]*(g[v]+1) + f[v]*g[u])%m; g[u] = g[u]*(g[v]+1)%m; } } ans = (ans + f[u])%m; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=1; i<=200000; i++) G[i].clear(); int pi; for(int i=2; i<=n; i++) { scanf("%d", &pi); G[i].push_back(pi); G[pi].push_back(i); } ans = 0; memset(f, 0, sizeof(f)); dfs(1, -1); // LL res = 0; // for(int i=1; i<=200000; i++) res = (res + f[i])%m; printf("%lld\n", ans); // printf("%lld\n", res); } return 0; }
相关文章推荐
- 十八
- Restore IP Addresses [Leetcode 解题报告]
- html5 postMessage解决跨域、跨窗口消息传递
- win7 writefile写磁盘失败解决
- 如何动态获取、设置Android控件的宽、高
- 单元测试
- .Net之美
- cocos2d-x实例学习(9)之CCCardinalSplineBy
- Leetcode:189. Rotate Array(JAVA)
- zabbix通过JMX 监控tomcat
- 关于手势 — 手势添加tag值
- [湖南省第六届大学生计算机程序设计竞赛]弟弟的作业
- android 保存mp4视频的办法
- 应用程序间的跳转
- ExtJs布局之accordion,fit,auto
- C++中cin输入类型不匹配解决方法
- Java servlet线程安全即解决办法
- 几种单例模式解析
- 寻找图的最少割边的算法
- 剪邮票(第七届蓝桥杯b组原题)