HDOJ题目4705 Y(简单树形DP+数学)

来源:互联网 发布:p城办事处优化器 编辑:程序博客网 时间:2024/05/18 18:42

Y

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


Problem Description
 

Sample Input
41 21 31 4
 

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

Source
2013 Multi-University Training Contest 10
 

Recommend
zhuyuanchen520   |   We have carefully selected several similar problems for you:  5315 5314 5313 5312 5311 
 题目大意:从一颗树上找3个节点,这三个节点之间没有一条路相连,
思路:用总的情况的个数减去满足三个节点之间有路的情况个数,满足的个数求法为选i节点,再选i的子树一个节点,再选树的其他部分一个节点,会重复,求出来除2
ac代码
#include<stdio.h>#include<string.h>#pragma comment(linker, "/STACK:16777216")int son[100010],head[100010],dig[100010],cnt,f[100010];struct s{int u,v,next;}edge[200020];void add(int u,int v){edge[cnt].u=u;edge[cnt].v=v;//edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;}int dfs(int u,int pre){son[u]=1;f[u]=pre;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(v==pre)continue;son[u]+=dfs(v,u);}return son[u];}int main(){int n;while(scanf("%d",&n)!=EOF){int i,j;memset(head,-1,sizeof(head));cnt=0;for(i=1;i<=n-1;i++){int u,v;scanf("%d%d",&u,&v);add(u,v);add(v,u);}dfs(1,-1);__int64 sum=0,a,b;for(i=1;i<=n;i++){__int64 temp=0;for(j=head[i];j!=-1;j=edge[j].next){int v=edge[j].v;if(v==f[i])a=n-son[i];elsea=son[v];b=n-a-1;temp+=a*b;}sum+=temp/2;}__int64 ans=(__int64)n*(n-1)*(n-2)/6-sum;printf("%I64d\n",ans);}}


0 0