HDU-4705-树形dp/组合数学

Y

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2762    Accepted Submission(s): 800


Problem Description
 

 

Sample Input
4 1 2 1 3 1 4
 

 

Sample Output
1
Hint
1. The only set is {2,3,4}. 2. Please use #pragma comment(linker, "/STACK:16777216")
 

 

Source
 

       可以先找到三个点的SIMPLE-PATH的数量,然后让C(N,3)-SIMPLE-PATH就是答案了。

      对于节点u,子树的节点个数为n1,n2,,,,,nk的话,以u为中点的SIMPLE-PATH的数量就是n1(n2+n3+...+nk)+n2(n3+...+nk)+.....+nk-1*nk,这一步可以在遍历儿子时迭代实现。

      别忘记还有一颗子树是父亲节点,N-sum[u].

   

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #pragma comment(linker, "/STACK:16777216")
 7 #define LL long long 
 8 vector<int>g[100005];
 9 LL sum[100005];
10 LL tot,N;
11 void dfs(int u,int pre){
12     sum[u]=1;
13     LL  res=0;
14     for(int i=0;i<g[u].size();++i){
15         if(g[u][i]==pre) continue;
16         dfs(g[u][i],u);
17         sum[u]+=sum[g[u][i]];
18         tot+=res*sum[g[u][i]];
19         res+=sum[g[u][i]];
20     }
21     tot+=res*(N-sum[u]);
22 }
23 int main()
24 {
25     while(cin>>N){int u,v;
26         tot=0;
27         for(int i=1;i<N;++i){
28             scanf("%d%d",&u,&v);
29             g[u].push_back(v);
30             g[v].push_back(u);
31         }
32         dfs(1,0);
33         LL tt=0;
34         LL ans=N*(N-1)*(N-2)/6;
35         cout<<ans-tot<<endl;
36         for(int i=1;i<=N;++i) g[i].clear();
37     }
38     return 0;
39 }

 

转载于:https://www.cnblogs.com/zzqc/p/8846050.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值