51nod1405(树形dp)
来源:互联网 发布:c语言比较三个数大小 编辑:程序博客网 时间:2024/06/05 04:37
链接:点击打开链接
题意:给定一棵无根树,假设它有n个节点,节点编号从1到n, 求任意两点之间的距离(最短路径)之和
代码:
#pragma comment(linker, "/STACK:102400000,102400000")#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;const long long SIZE=100005;long long n,dp[SIZE],num[SIZE],used[SIZE];vector<long long> G[SIZE];void dfs1(long long s,long long sum){ long long i,tmp; dp[1]+=sum; //以1为根节点算出根节点 used[s]=1; //到所有节点的和 for(i=0;i<G[s].size();i++){ tmp=G[s][i]; if(G[tmp].size()&&!used[tmp]){ dfs1(tmp,sum+1); num[s]+=num[tmp]; //求出每个节点包括自己所 } //含的子树中节点的总数 }}void dfs2(long long s){ long long i,tmp; used[s]=1; for(i=0;i<G[s].size();i++){ tmp=G[s][i]; if(!used[tmp]){ //当前节点到其他节点的路径 dp[tmp]+=(dp[s]+(n-num[tmp])-num[tmp]); //和,可由父节点的节点数和 dfs2(tmp); //当前节点的节点数所推导出来 } }}int main(){ long long a,b,i; while(scanf("%I64d",&n)!=EOF){ for(i=1;i<=n;i++) G[i].clear(); fill(num,num+n+1,1); memset(dp,0,sizeof(dp)); memset(used,0,sizeof(used)); for(i=0;i<n-1;i++){ scanf("%I64d%I64d",&a,&b); //因为是无向边 G[a].push_back(b); G[b].push_back(a); } dfs1(1,0); memset(used,0,sizeof(used)); dfs2(1); for(i=1;i<=n;i++) printf("%I64d\n",dp[i]); } return 0;}
0 0
- 51nod1405(树形dp)
- 51NOD1378 树形DP + 贪心
- 51Nod - 1737 树形dp
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形dp
- 树形DP
- 树形DP
- 树形DP
- 树形DP
- 树形dp
- 树形dp
- 树形dp
- 树形dp
- 树形DP
- 树形DP
- Nginx自定义404页面(Linux环境下配置)
- 程序员,你头上长草了吗?
- SPOJ NKTEAM - Team Selection
- 【java-之路】学习反射[基础]
- samba共享服务器配置
- 51nod1405(树形dp)
- iOS中锁定竖屏不让其横屏的方法
- LayoutAnimationController为视图添加动画效果
- CSS 的继承、层叠和特殊性[修改版]
- Apache Maven 入门篇 ( 上 )
- 最小生成树
- 自定义个TabLayout
- Servlet 基础02
- POJ 2828 排队插队(线段树_好题)