题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3534

题意:

给你一棵树,问你有多少对点的距离等于树的直径。

思路:

dp[i][0]表示在i的子树中 离i最远的距离,dp[i][1]是次远距离。   cnt[i][0]则是最远的点的数量,cnt[i][1]表示次远的数量。

up[i]表示以i向上 离i最远的距离。   up_cnt[i]表示向上最远的数量。

写的有点麻烦,调试了2小时。。。

 //#pragma comment(linker, "/STACK:102400000, 102400000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
typedef pair <int, int> P;
const int N = 2e5 + ;
int dp[N][];
int cnt[N][];
int up[N];
int cnt_up[N];
int son[N][];
vector <P> G[N]; void dfs1(int u, int p) {
dp[u][] = dp[u][] = ;
son[u][] = son[u][] = u;
cnt[u][] = cnt[u][] = ;
int tmp = ;
for(int i = ; i < G[u].size(); ++i) {
P temp = G[u][i];
int v = temp.first;
if(v == p)
continue;
dfs1(v, u);
if(dp[v][] + temp.second > dp[u][]) {
dp[u][] = dp[u][];
son[u][] = son[u][];
cnt[u][] = cnt[u][];
dp[u][] = dp[v][] + temp.second;
son[u][] = v;
cnt[u][] = cnt[v][];
tmp = cnt[v][];
} else if(dp[v][] + temp.second == dp[u][]) {
cnt[u][] += cnt[v][];
cnt[u][] = cnt[u][] - tmp;
dp[u][] = dp[u][];
son[u][] = v;
} else if(dp[v][] + temp.second > dp[u][]) {
dp[u][] = dp[v][] + temp.second;
cnt[u][] = cnt[v][];
son[u][] = v;
} else if(dp[v][] + temp.second == dp[u][]) {
cnt[u][] += cnt[v][];
}
}
} void dfs2(int u, int p) {
for(int i = ; i < G[u].size(); ++i) {
P temp = G[u][i];
int v = temp.first;
if(v == p)
continue;
if(dp[u][] == temp.second + dp[v][]) {
//up[v] = max(up[u], dp[u][0]) + temp.second;
if(dp[u][] == ) {
cnt_up[v] = cnt_up[u];
up[v] = up[u] + temp.second;
dfs2(v, u);
continue;
}
if(up[u] > dp[u][]) {
up[v] = up[u] + temp.second;
cnt_up[v] = cnt_up[u];
} else if(dp[u][] > up[u]) {
up[v] = dp[u][] + temp.second;
if(dp[u][] == dp[u][])
cnt_up[v] = cnt[u][] - cnt[v][];
else
cnt_up[v] = cnt[u][];
} else {
if(dp[u][] == dp[u][])
cnt_up[v] = cnt[u][] - cnt[v][];
else
cnt_up[v] = cnt[u][];
cnt_up[v] += cnt_up[u];
up[v] = dp[u][] + temp.second;
}
} else {
//up[v] = max(up[u], dp[u][1]) + temp.second;
if(up[u] > dp[u][]) {
up[v] = up[u] + temp.second;
cnt_up[v] = cnt_up[u];
} else if(dp[u][] > up[u]) {
up[v] = dp[u][] + temp.second;
cnt_up[v] = cnt[u][];
} else {
cnt_up[v] = cnt_up[u] + cnt[u][];
up[v] = dp[u][] + temp.second;
}
}
dfs2(v, u);
}
} int main()
{
int n, u, v, c;
while(~scanf("%d", &n)) {
for(int i = ; i <= n; ++i) {
G[i].clear();
}
for(int i = ; i < n; ++i) {
scanf("%d %d %d", &u, &v, &c);
G[u].push_back(make_pair(v, c));
G[v].push_back(make_pair(u, c));
}
dfs1(, -);
cnt_up[] = ;
dfs2(, -);
int Max = ;
for(int i = ; i <= n; ++i) {
//cout << dp[i][0] << " - " << up[i] << endl;
Max = max(Max, max(dp[i][], up[i]));
}
LL ans = ;
for(int i = ; i <= n; ++i) {
if(Max == dp[i][]) {
ans += (LL)cnt[i][];
}
if(Max == up[i]) {
ans += (LL)cnt_up[i];
}
}
printf("%d %lld\n", Max, ans/);
}
return ;
}

HDU 3534 Tree (经典树形dp)的更多相关文章

  1. hdu 5909 Tree Cutting [树形DP fwt]

    hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...

  2. HDU 2196 Computer(经典树形DP)

    题意自己看(猜) 题解 这题很经典,就是记录dp[i][0/1/2]分别代表,从i点向下最大和次大深度,和向上最大深度. 然后转移就行了. 我的写法可能太丑了.死活调不出来,写了一个漂亮的 #incl ...

  3. HDU 6035---Colorful Tree(树形DP)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  4. HDU - 5909 Tree Cutting (树形dp+FWT优化)

    题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值.求一棵树中,连通子树值为[0,m)的个数. 分析: 设\(dp[i][j]\)为根为i,值为j的子树的个数. 则\(dp[i][j\o ...

  5. HDU.5909.Tree Cutting(树形DP FWT/点分治)

    题目链接 \(Description\) 给定一棵树,每个点有权值,在\([0,m-1]\)之间.求异或和为\(0,1,...,m-1\)的非空连通块各有多少个. \(n\leq 1000,m\leq ...

  6. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  7. HDU 5834 Magic boy Bi Luo with his excited tree(树形dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=5834 题意: 一棵树上每个节点有一个价值$Vi$,每个节点只能获得一次,每走一次一条边要花费$Ci$,问从各个节 ...

  8. ural 1018 Binary Apple Tree(树形dp | 经典)

    本文出自   http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...

  9. HDU 1561 The more, The Better 经典树形DP

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. 【js】window.onscroll 无效问题

    body 设置为height:100% 导致window.onscroll 无效

  2. python爬虫基础13-selenium大全7/8-异常

    Selenium笔记(7)异常 本文集链接:https://www.jianshu.com/nb/25338984 完整文档 Exceptions that may happen in all the ...

  3. 中国电信物联网平台入门学习笔记2: DOME程序分析

    "墨子号NB-IOT开发板"提供的dome: 程序只要分为延时,定时器,串口通讯…… 工程文件在:…\STM32L1xx_StdPeriph_Lib_V1.3.1\Project\ ...

  4. Django之用户认证

    用户认证组件简介 功能:用session记录登录验证状态 前提:必须使用django自带的auth_user表.那这里有的同学就会有疑问了,自己不能创建自己的用户表吗? 当然可以,用户认证组件虽然只针 ...

  5. 将系统从.Net Core2.0升级到.Net Core2.1

    最近将手头的一个.Net Core2.0开发的小系统升级到最新的Core2.1.升级期间遇到了一些问题,现将问题以及解决方法整理汇总一下. 一是作为笔记,二也为跟各位分享一下.如过能帮到看到这帖子的人 ...

  6. rocketmq源码分析1-benchmark学习

    benchmark 分析 组成部分 三个java类,都含有main方法,可选的传递一些参数,诸如测试线程数量,消息体积大小.三个类分别用于测试普通生产者,事务生产者,消费者.生产者 默认64个测试线程 ...

  7. python - 接口自动化测试实战 - case1 - 再次优化版

    本次优化: 1.  各级分Package 2.  封装[ReadExcel]类 3.  封装[ReadConfig]类 4.  封装[GetLog]类 5.  引入ddt数据驱动测试,优化测试用例代码 ...

  8. day03_05 Python程序文件执行和与其他编程语言对比

    python在windows操作系统上是没有的,但是在linux上默认就有python 执行python程序的方式有两种: 1.交互器,缺点 程序不能永久保存,主要用于简单的语法测试 2.文件执行 对 ...

  9. python学习-- for和if结合使用

    for和if结合使用: <h1> {% for i in contents %} {{ i }}{# 注意i也要用两个大括号 #} {% endfor %} </h1> < ...

  10. python面向对象、模块讲解

    (1)模块的介绍: 1.什么是模块  模块是一系列功能的集合体  常见的模块形式(自定义模块.第三方模块.内置模块):   1.一个module.py文件就是一个模块,文件名是module.py,而模 ...