hdu 4705(树形DP)

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

思路:反面考虑,用总的方案数减去A,B,C三点在同一路径上的方案数。于是我们可以确定中间点B,在当前以B为根求得的son中任选一个,在剩下的节点n-tmp-1(tmp为已经求得的B的儿子的个数)中任选一个,产生tmp*(n-tmp-1)中组合。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 #define MAXN 100100
 7 #pragma comment(linker, "/STACK:16777216")
 8 
 9 struct Edge{
10     int v,next;
11 }edge[MAXN*4];
12 
13 int NE;
14 long long n;
15 int head[MAXN];
16 
17 void Insert(int u,int v)
18 {
19     edge[NE].v=v;
20     edge[NE].next=head[u];
21     head[u]=NE++;
22 }
23 
24 
25 bool mark[MAXN];
26 long long sum,ans;
27 
28 int dfs(int u)
29 {
30     mark[u]=true;
31     int son,tmp=0;
32     for(int i=head[u];i!=-1;i=edge[i].next){
33         int v=edge[i].v;
34         if(mark[v])continue;
35         son=dfs(v);//当前分支儿子的个数
36         tmp+=son;//已经求出的儿子的个数
37         ans+=(long long )(n-1-tmp)*son;
38     }
39     return tmp+1;
40 }
41 
42 
43 int main()
44 {
45     int u,v;
46     while(~scanf("%I64d",&n)){
47         NE=0;
48         memset(head,-1,sizeof(head));
49         for(int i=1;i<n;i++){
50             scanf("%d%d",&u,&v);
51             Insert(u,v);
52             Insert(v,u);
53         }
54         memset(mark,false,sizeof(mark));
55         ans=0;
56         dfs(1);
57         sum=n*(n-1)*(n-2)/6;
58         printf("%I64d\n",sum-ans);
59     }
60     return 0;
61 }
View Code

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值