hdu4705Y

链接

这题可以算树形DP吧 树上的递推

对于树上的某个节点 反着算比较好做 就是算有多少有simple路径的

固定某个节点u 另两个节点 有两种取法

1.从不同子树里各选一个

2.从所有子树里选一个 再从以u为跟的子树 外面选一个

求总和

 1 #pragma comment(linker, "/STACK:16777216")

 2 #include <iostream>

 3 #include<cstdio>

 4 #include<cstring>

 5 #include<algorithm>

 6 #include<stdlib.h>

 7 using namespace std;

 8 #define N 100010

 9 #define LL __int64

10 struct node

11 {

12     int u,v,next;

13 }ed[N<<1];

14 int head[N],t;

15 LL sum[N],ans,n;

16 void init()

17 {

18     t = 0;

19     memset(head,-1,sizeof(head));

20 }

21 void add(int u,int v)

22 {

23     ed[t].u = u;

24     ed[t].v = v;

25     ed[t].next = head[u];

26     head[u] = t++;

27 }

28 LL dfs(int pre,int u)

29 {

30     int i;

31     LL s=0,ss;

32     sum[u] = 1;

33     for(i = head[u]; i!=-1 ; i = ed[i].next)

34     {

35         int v = ed[i].v;

36         if(v==pre) continue;

37         ss = dfs(u,v);

38         ans+=s*ss;

39         s+=ss;

40         sum[u]+=ss;

41     }

42     ans+=s*(n-sum[u]);

43     return sum[u];

44 }

45 int main()

46 {

47     int i,u,v;

48     while(scanf("%I64d",&n)!=EOF)

49     {

50         init();ans=0;

51         memset(sum,0,sizeof(sum));

52         for(i = 1 ; i < n ; i++)

53         {

54             scanf("%d%d",&u,&v);

55             add(u,v);

56             add(v,u);

57         }

58         dfs(-1,1);

59         LL oo = (n-1)*n/2*(n-2)/3;

60         printf("%I64d\n",oo-ans);

61     }

62     return 0;

63 }
View Code

 

你可能感兴趣的:(HDU)