zoukankan      html  css  js  c++  java
  • 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
    ",sum-ans);
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    Nhibernate1
    控制反转(IoC)
    Windbg是windows平台上强大的调试器
    Java 7 语法新特性
    区间数据计算
    红黑树数据结构剖析
    .net下灰度模式图像
    如何配置Hyper-V的虚拟机通过主机网络上网 (NAT)
    产品落地
    poj-3898 Software Industry Revolution DP
  • 原文地址:https://www.cnblogs.com/wally/p/3276933.html
Copyright © 2011-2022 走看看