例题:HDU2376   HDU6446(2018CCPC网络赛)

思路:求任意两点间距离和可以转换为->路径长度乘经过路径次数的和。

求经过次数:设这条边两端的点,被经过的次数分别为A和B,那么这条边被经过的次数就是A*B,它对总距离和的贡献就是(A*B*此边长度)。

每条边两端点经过次数的计算,可以用一次dfs解决。

任取一点为根,在dfs的过程中,对每个点k记录其子树包含的点数(包括其自身),设点数为sum[k],则k的父亲一侧的点数即为N-sum[k]。这个统计可以和遍历同时进行。故时间复杂度为O(n)。

HDU2376:求完距离和,再除以总路径数N*(N-1)/2,即为最后所求

HDU6446:根据插点排序的思路,再乘以(N-1)! * 2,即为最后所求

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. const int maxn = ;
  6.  
  7. int sum[maxn], n;
  8. ll dp[maxn];
  9.  
  10. struct Edge
  11. {
  12. int v, w;
  13. Edge(int _v = , int _w = )
  14. {
  15. v = _v;
  16. w = _w;
  17. }
  18. };
  19. vector<Edge> tree[maxn];
  20.  
  21. void dfs(int cur, int father)
  22. {
  23. sum[cur] = ;
  24. for(int i = ; i < tree[cur].size(); i++)
  25. {
  26. int son = tree[cur][i].v;
  27. ll len = tree[cur][i].w;
  28. if(father == son)
  29. continue;
  30. dfs(son, cur);
  31. sum[cur] += sum[son];
  32. dp[cur] += dp[son] + (n-sum[son]) * sum[son] * len;
  33. }
  34. }
  35.  
  36. int main()
  37. {
  38. int u, v, w, T;
  39. scanf("%d", &T);
  40. while(T--)
  41. {
  42. scanf("%d", &n);
  43. for(int i = ; i < n; i++)
  44. tree[i].clear();
  45. memset(sum, , sizeof(sum));
  46. memset(dp, , sizeof(dp));
  47. for(int i = ; i < n-; i++)
  48. {
  49. scanf("%d%d%d", &u, &v, &w);
  50.  
  51. tree[u].push_back(Edge(v,w));
  52. tree[v].push_back(Edge(u,w));
  53. }
  54. dfs(, -); //设0为根节点
  55. printf("%I64d\n", dp[]); //这里输出的是距离和
  56. }
  57. return ;
  58. }

树形DP--求树上任意两点间距离和的更多相关文章

  1. 2019CCPC-江西省赛 -A Cotree (树形DP,求树上一点到其他点的距离之和)

    我是傻逼我是傻逼 #include<bits/stdc++.h> using namespace std; const int maxn=4e5+50; typedef long long ...

  2. 浅谈关于树形dp求树的直径问题

    在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径. 求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这 ...

  3. HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  4. 树形dp - 求树的直径

    随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...

  5. hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解

    题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...

  6. 2017 Wuhan University Programming Contest (Online Round) B Color 树形dp求染色方法数

    /** 题目:Color 链接:https://oj.ejq.me/problem/23 题意:给定一颗树,将树上的点最多染成m种颜色,有些节点不可以染成某些颜色.相邻节点颜色不同.求染色方法数. 思 ...

  7. HDU - 3899 JLUCPC(树形dp求距离和)

    JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Co ...

  8. 树形DP求树的重心 --SGU 134

    令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...

  9. xdoj-1319 求树上任意一点的最大距离----利用树的直径

    1 #include <bits/stdc++.h> using namespace std; ; vector < vector <int> > g(N); in ...

随机推荐

  1. mybatis 学习二 MyBatis简介与配置MyBatis+Spring+MySql

    1.2.2建立MySql数据库 在C:\Program Files\MySQL\MySQL Server 5.7\bin下面: 首先连接MySQL:        mysql  -u root -p ...

  2. Python中str.format()字典及list传入详解

  3. leetcode458

    原本没有思路,参考了网上的解题思路,自己独立完成了代码. int poorPigs(int buckets, int minutesToDie, int minutesToTest) { ; ; wh ...

  4. JS写一个简单的程序,判断年份是平年还是闰年

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. awk简要使用

    1          前言 awk是Unix环境下一种非常好的语言,适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行特殊技巧程序设计.对于短消息来说,比如处理话单文件,使用awk就非常方便 ...

  6. python中注释的书写

    与c和c++的//不同的是,在python中我们使用#来进行注释 每个#所在的那一行都可以叫做注释:

  7. 【转】webService概述

    一.序言: 大家或多或少都听过WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成分.但是不得不承认的是We ...

  8. redis的特性

  9. JAVA基础知识总结13(同步)

    好处:解决了线程安全问题. 弊端:相对降低性能,因为判断锁需要消耗资源,还容易产生了死锁. 定义同步是有前提的: 1,必须要有两个或者两个以上的线程,才需要同步. 2,多个线程必须保证使用的是同一个锁 ...

  10. nodejs的POST请求

    http://blog.csdn.net/puncha/article/details/9015317 Nodejs 发送HTTP POST请求实例 2013-06-03 17:55 71745人阅读 ...