hdu 4705 树形dp

来源:互联网 发布:怎样装修手机淘宝店铺 编辑:程序博客网 时间:2024/06/07 05:28

题意:树上任意三个点不在一条路径上,统计这样的三点集合有多少种。

三个点构成的路方案数 S = C(n,3)=n*(n-1)*(n-2)/6

用S减去三个点在一条路径上的数目就是答案。

枚举中间点作为第二个点,在它的第K棵子树上找一个点作为第一个点,在剩下的,没有枚举过的结点里,找一个点作为第三个点。数目相乘。

这样问题就变成了统计结点的子节点问题,简单的树形dp

#include <iostream>  #include <cstdio>  #include <algorithm>  #include <cstdio>  #include <cstring>  #include <vector>  #pragma comment(linker, "/STACK:24000000")using namespace std;  vector<int> tree[100005];  typedef long long ll;  ll ans,n;  ll dfs(int now,int last){   int v;   ll son=0,sum=0;   for(int i=0;i<tree[now].size();i++)   {         v=tree[now][i];         if(v==last) continue;         sum+=son=dfs(v,now);         ans+=(n-sum-1)*son;   }   return sum+1;}int main()  {      int a,b;      while(~scanf("%lld",&n))      {          for(int i=1;i<=n;i++) tree[i].clear();          for(int i=1;i<n;i++)          {              scanf("%d%d",&a,&b);              tree[a].push_back(b);              tree[b].push_back(a);          }          ans=0;          dfs(1,0);          printf("%I64d\n",n*(n-1)*(n-2)/6-ans);      }      return 0;  }  

0 0
原创粉丝点击