分析:首先树形dp(dfs计算出每个点为根节点的子树的最长距离和次长距离),然后找出L=dis[u][0]+dis[u][1]最长的那个点u,然后在以u为根节点dfs,统计长度为L的条数:具体做法:把u的儿子节点为根节点的子树深搜遍历到每个叶子节点,用h[dist[v]]统计该子树中u到v的距离,然后对于遍历过的叶子节点且不再当前子树中的s[L-dist[v]]的个数加到ans中,最后ans即为所求条数:

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include"stdio.h"
  3. #include"string.h"
  4. #include"stdlib.h"
  5. #include"queue"
  6. #include"algorithm"
  7. #include"string.h"
  8. #include"string"
  9. #include"math.h"
  10. #include"vector"
  11. #include"stack"
  12. #include"map"
  13. #define eps 1e-4
  14. #define inf 0x3f3f3f3f
  15. #define M 100009
  16. #define PI acos(-1.0)
  17. using namespace std;
  18. struct node
  19. {
  20. int u,v,next;
  21. __int64 w;
  22. }edge[M*2];
  23. int t,head[M],belong[M],dis[M][4],degree[M];
  24. int cnt;
  25. __int64 dist[M],a[M],L,ans;
  26. map<__int64,int>s,h;
  27. void init()
  28. {
  29. t=0;
  30. memset(head,-1,sizeof(head));
  31. }
  32. void add(int u,int v,int w)
  33. {
  34. edge[t].u=u;
  35. edge[t].v=v;
  36. edge[t].w=w;
  37. edge[t].next=head[u];
  38. head[u]=t++;
  39. }
  40. void dfs(int u,int f)
  41. {
  42. dis[u][0]=0;
  43. dis[u][1]=0;
  44. for(int i=head[u];~i;i=edge[i].next)
  45. {
  46. int v=edge[i].v;
  47. if(v==f)continue;
  48. dfs(v,u);
  49. if(dis[u][0]<dis[v][0]+edge[i].w)
  50. {
  51. dis[u][1]=dis[u][0];
  52. dis[u][0]=dis[v][0]+edge[i].w;
  53. }
  54. else if(dis[u][1]<dis[v][0]+edge[i].w)
  55. dis[u][1]=dis[v][0]+edge[i].w;
  56. }
  57. }
  58. void dfs2(int u,int f);
  59. void dfs1(int u,int f)
  60. {
  61. s.clear();
  62. for(int i=head[u];~i;i=edge[i].next)
  63. {
  64. int v=edge[i].v;
  65. if(v==f)continue;
  66. h.clear();
  67. dist[v]=edge[i].w;
  68. cnt=0;
  69. dfs2(v,u);
  70. for(int j=0;j<cnt;j++)
  71. {
  72. s[a[j]]+=h[a[j]];
  73. }
  74. }
  75. }
  76. void dfs2(int u,int f)
  77. {
  78. if(degree[u]==1)
  79. {
  80.  
  81. if(h[dist[u]]==0)
  82. a[cnt++]=dist[u];
  83. h[dist[u]]++;
  84. if(s[L-dist[u]])
  85. {
  86. ans+=s[L-dist[u]];
  87. //printf("%d %d\n",s[L-dist[u]],h[dist[u]]);
  88. }
  89. }
  90. for(int i=head[u];i!=-1;i=edge[i].next)
  91. {
  92. int v=edge[i].v;
  93. if(v==f)continue;
  94. dist[v]=dist[u]+edge[i].w;
  95. dfs2(v,u);
  96. }
  97. }
  98. int main()
  99. {
  100. int n,i,a,b;
  101. __int64 c;
  102. while(scanf("%d",&n)!=-1)
  103. {
  104. init();
  105. memset(degree,0,sizeof(degree));
  106. for(i=1;i<n;i++)
  107. {
  108. scanf("%d%d%I64d",&a,&b,&c);
  109. add(a,b,c);
  110. add(b,a,c);
  111. degree[a]++;
  112. degree[b]++;
  113. }
  114. if(n==1)
  115. {
  116. printf("0 1\n");
  117. continue;
  118. }
  119. if(n==2)
  120. {
  121. printf("%I64d 1\n",edge[0].w);
  122. continue;
  123. }
  124. for(i=1;i<=n;i++)
  125. {
  126. if(degree[i]>1)
  127. {
  128. dfs(i,-1);
  129. break;
  130. }
  131. }
  132. int id=1;
  133. L=dis[id][0]+dis[id][1];
  134. for(i=2;i<=n;i++)
  135. {
  136. if(dis[id][0]+dis[id][1]<dis[i][0]+dis[i][1])
  137. {
  138. L=dis[i][0]+dis[i][1];
  139. id=i;
  140. }
  141. }
  142. ans=0;
  143. dfs1(id,-1);
  144. printf("%I64d %I64d\n",L,ans);
  145. }
  146. }

树形DP(统计直径的条数 HDU3534)的更多相关文章

  1. hdoj3534(树形dp,求树的直径的条数)

    题目链接:https://vjudge.net/problem/HDU-3534 题意:给出一棵树,求树上最长距离(直径),以及这样的距离的条数. 思路:如果只求直径,用两次dfs即可.但是现在要求最 ...

  2. 树形DP 统计树中长度为K的路径数量——Distance in Tree

    一.问题描述 给出一棵n个节点的树,统计树中长度为k的路径的条数(1<=n<=50000 , 1<=k<=500). 二.解题思路 设d[i][k]表示以i为根节点长度为k的路 ...

  3. bzoj1912 树形dp求直径(新写法),求直径的两端点

    通过回溯法可以求出直径的两个端点,同时注意有负权边的树求直径不可以用两次dfs来求,而必须用dp做 /* 分情况讨论问题 一条边也不加的情况,显然每条边要扫描两次, 该情况的答案是2(n-1) 只加一 ...

  4. tarjan算法求缩点+树形DP求直径

    hdu4612 Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  5. mysql根据分组和条件查询以后如何统计记录的条数

    1.子查询,查询出的数据随便起一个别名,然后根据分组和条件查询出的数据,作为一个具有一列的一个表,然后外面的查询查询这个数据表的这一列的总数,即可. SELECT COUNT( * ) FROM ( ...

  6. Luogu4630 APIO2018 Duathlon 圆方树、树形DP

    传送门 要求的是一条按顺序经过\(s,t,c\)三个点的简单路径.简单路径的计数问题不难想到点双联通分量,进而使用圆方树进行求解. 首先将原图缩点,对于一个大小为\(size\)的点双联通分量内,在这 ...

  7. 洛谷 P2986 [USACO10MAR]Great Cow Gat…(树形dp+容斥原理)

    P2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat… 题目描述 Bessie is planning the annual Great Cow Gathering for c ...

  8. Codeforces 919D Substring (拓扑排序+树形dp)

    题目:Substring 题意:给你一个有向图, 一共有n个节点 , m条变, 一条路上的价值为这个路上出现过的某个字符最多出现次数, 现求这个最大价值, 如果价值可以无限大就输出-1. 题解:当这个 ...

  9. HDU2242 考研路茫茫——空调教室 (双联通分+树形DP)

    考研路茫茫——空调教室 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. wdate-year-month-week-gategory-amount-coin

    ---2016-12-02 19:46:39 the whole table DISTINCT field SUM(field) COUNT(field) --- 888983 rows OK SEL ...

  2. 【转】最简单的CI框架入门示例--数据库取数据

    1.下载CI框架(自己找) 2.配置 database.php配置:    为数据库服务器设置 connection 参数: $db['default']['hostname'] = "yo ...

  3. osgi 命令

    安装命令 install reference:file:D:/workspace/workspace-osgi/MsgBoxCreateModule 根据 返回的 ID再运行start

  4. SQL2005的cte递归查询子树

    ;with cteas(select id,caption,parentid,1 Gen from skywfflow where parentid =0UNION ALL select a.id,a ...

  5. SQL Server加密存储过程的破解

    建好sp后,在“连接到数据库引擎”对话框的“服务器名称”框中,键入 ADMIN:,并在其后继续键入服务器实例的名称.例如,若要连接到名为 ACCT\PAYABLE 的服务器实例,请键入 ADMIN:A ...

  6. Android Studio工具修理集

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 1.Common依赖项目找不到.因为主项目没有引进setting.gradle 2.从Eclipse ...

  7. php--group by

    1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用 group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by ...

  8. ArcGIS API for JavaScript 4.0(一)

    原文:ArcGIS API for JavaScript 4.0(一) 最近ArcGIS推出了ArcGIS API for JavaScript 4.0,支持无插件3D显示,而且比较Unity和Sky ...

  9. -tableView: cellForRowAtIndexPath:方法不执行问题

    今天在学习UItableView 的时候,定义了一个属性 @property (weak, nonatomic) NSMutableArray *dataList: 在ViewDidLoad方法方法中 ...

  10. js操作table倒叙显示序号的问题

    今天遇到一奇葩问题,就是在js添加table时,序号是倒叙显示的,而且数据库查出来时正序的,为什么显示是倒叙的呢? 我百度一番,终于有了结果: var newRow=table.insertRow(- ...