分析:首先树形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即为所求条数:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"queue"
#include"algorithm"
#include"string.h"
#include"string"
#include"math.h"
#include"vector"
#include"stack"
#include"map"
#define eps 1e-4
#define inf 0x3f3f3f3f
#define M 100009
#define PI acos(-1.0)
using namespace std;
struct node
{
int u,v,next;
__int64 w;
}edge[M*2];
int t,head[M],belong[M],dis[M][4],degree[M];
int cnt;
__int64 dist[M],a[M],L,ans;
map<__int64,int>s,h;
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void dfs(int u,int f)
{
dis[u][0]=0;
dis[u][1]=0;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
dfs(v,u);
if(dis[u][0]<dis[v][0]+edge[i].w)
{
dis[u][1]=dis[u][0];
dis[u][0]=dis[v][0]+edge[i].w;
}
else if(dis[u][1]<dis[v][0]+edge[i].w)
dis[u][1]=dis[v][0]+edge[i].w;
}
}
void dfs2(int u,int f);
void dfs1(int u,int f)
{
s.clear();
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
h.clear();
dist[v]=edge[i].w;
cnt=0;
dfs2(v,u);
for(int j=0;j<cnt;j++)
{
s[a[j]]+=h[a[j]];
}
}
}
void dfs2(int u,int f)
{
if(degree[u]==1)
{ if(h[dist[u]]==0)
a[cnt++]=dist[u];
h[dist[u]]++;
if(s[L-dist[u]])
{
ans+=s[L-dist[u]];
//printf("%d %d\n",s[L-dist[u]],h[dist[u]]);
}
}
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
dist[v]=dist[u]+edge[i].w;
dfs2(v,u);
}
}
int main()
{
int n,i,a,b;
__int64 c;
while(scanf("%d",&n)!=-1)
{
init();
memset(degree,0,sizeof(degree));
for(i=1;i<n;i++)
{
scanf("%d%d%I64d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
degree[a]++;
degree[b]++;
}
if(n==1)
{
printf("0 1\n");
continue;
}
if(n==2)
{
printf("%I64d 1\n",edge[0].w);
continue;
}
for(i=1;i<=n;i++)
{
if(degree[i]>1)
{
dfs(i,-1);
break;
}
}
int id=1;
L=dis[id][0]+dis[id][1];
for(i=2;i<=n;i++)
{
if(dis[id][0]+dis[id][1]<dis[i][0]+dis[i][1])
{
L=dis[i][0]+dis[i][1];
id=i;
}
}
ans=0;
dfs1(id,-1);
printf("%I64d %I64d\n",L,ans);
}
}

树形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. AP_总体业务及方案

    AP关键业务点说明 关键业务点 说明 预付款余额收回 1. 在应付款管理系统中输入一张虚拟发票,该发票的目的是在系统中冲减对供应商的预付款额,其金额等于预付款的未核销金额,供应商为原供应商. 借:其他 ...

  2. java Exchanger 2

    //Listing 6-3. Using an Exchanger to Swap Buffers import java.util.ArrayList; import java.util.List; ...

  3. Android 的上下文菜单: Context Menu,registerForContextMenu(getListView())

    概述: Android 的上下文菜单类似于 PC 上的右键菜单.当为一个视图注册了上下文菜单之后,长按(2 秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单.任何视图都可以注册上下文菜单,不过, ...

  4. I方法 thinkphp

    function I($name,$default=null,$filter=null,$datas=null) { static $_PUT = null; $default_filter='htm ...

  5. AutoHotKey使用:空格键坏了怎么办?

    ;RCtrl:: RAlt:: Send, {space} Return http://ahkscript.org/ https://autohotkey.com/download/

  6. 去除Html标签

    public static string ParseTags(string Htmlstring)     {         //删除脚本          Htmlstring = Regex.R ...

  7. 20145211《Java程序设计》第5周学习总结——独上高楼,望尽天涯路

    教材学习内容总结 异常处理 JAVA异常 异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.异常就是出现在运行时出现不正常 ...

  8. JS-009-屏幕分辨率、浏览器显示区域、元素位置获取

    此文简略讲述有关屏幕大小.元素位置及大小获取. 执行文中脚本时,请先打开 Chrome 浏览器,并切换至开发者工具的控制台,并打开网址:http://www.yixun.com/,文中元素事例为页面元 ...

  9. SQL Server 视图修改后有错怎么办?

    sp_refreshview 视图名:刷新指定视图 spsqlrefreshallviews:刷新全部视图

  10. mongoDB命令

    . getLastError db.runCommand({getLastError:}) . buildInfo //返回mongoDB的服务器版本号和操作系统类型 db.runCommand({} ...