HDU 3534 Tree (经典树形dp)
题目链接: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)的更多相关文章
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
- HDU 2196 Computer(经典树形DP)
题意自己看(猜) 题解 这题很经典,就是记录dp[i][0/1/2]分别代表,从i点向下最大和次大深度,和向上最大深度. 然后转移就行了. 我的写法可能太丑了.死活调不出来,写了一个漂亮的 #incl ...
- HDU 6035---Colorful Tree(树形DP)
题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...
- HDU - 5909 Tree Cutting (树形dp+FWT优化)
题意:树上每个节点有权值,定义一棵树的权值为所有节点权值异或的值.求一棵树中,连通子树值为[0,m)的个数. 分析: 设\(dp[i][j]\)为根为i,值为j的子树的个数. 则\(dp[i][j\o ...
- HDU.5909.Tree Cutting(树形DP FWT/点分治)
题目链接 \(Description\) 给定一棵树,每个点有权值,在\([0,m-1]\)之间.求异或和为\(0,1,...,m-1\)的非空连通块各有多少个. \(n\leq 1000,m\leq ...
- 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 ...
- HDU 5834 Magic boy Bi Luo with his excited tree(树形dp)
http://acm.hdu.edu.cn/showproblem.php?pid=5834 题意: 一棵树上每个节点有一个价值$Vi$,每个节点只能获得一次,每走一次一条边要花费$Ci$,问从各个节 ...
- ural 1018 Binary Apple Tree(树形dp | 经典)
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- 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 ...
随机推荐
- python3 完全平方数(循环)
题目 一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 代码: for i in range(1,85): if 168 % i == 0: j = 168 ...
- OpenCV中图像的BGR格式及Img对象的属性说明
1. 图像的BGR格式说明 OpenCV中图像读入的数据格式是numpy的ndarray数据格式.是BGR格式,取值范围是[0,255]. 如下图所示,分为三个维度: 第一维度:Height 高度,对 ...
- Statues CodeForces - 129C(bfs)
In this task Anna and Maria play a game with a very unpleasant rival. Anna and Maria are in the oppo ...
- Java装饰者模式(Decorator)
一.定义 装饰模式的设计理念主要是以对客户端透明的方式动态扩展对象的功能,是继承关系的一个替代(继承会产生大量的子类,而且代码有冗余).装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展.装饰 ...
- linux学习-用户的特殊 shell 与 PAM 模块
特殊的 shell, /sbin/nologin 『无法登入』指的是:『这个使用者无法使用 bash 或其他 shell 来登入系统』而已, 并不是说这个账号就无法使用其他的系统资源! 让某个具有 / ...
- Linux任务计划、周期性任务执行
Linux任务计划.周期性任务执行 周期性任务执行: cron 守护进程(crond):服务,不间断地运行于后台 # service crond {start|stop|status|restart} ...
- Android自动化测试如何获取坐标点?
有以下三种方法: 1.打开开发者选项中的“显示指针位置”: 英文文版本为Settings->Developer option->Show touches(on)->Pointer l ...
- STM8时基单元
STM8时基单元 时基单元包含: 16位向上/向下计数器 16位自动重载寄存器 重复计数器 预分频器 (图29:STM8 时基单元) 16位计数器,预分频器,自动重载寄存器和重复计数器寄存器都可以通过 ...
- BZOJ 2465: [中山市选2009]小球
难度在于读题 #include<cstdio> #include<algorithm> using namespace std; int a[1000005]; struct ...
- EXCEL常用命令
查找和选择:定位条件(定位空值.错误值) 选择性粘贴