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 ...
随机推荐
- 【laravel】Laravel 5 TokenMismatchException on PHP 5.6.9
When I realized this was only happening in IE and Chrome, but not Firefox, it led me to the fix. The ...
- UVa 10655 Contemplation! Algebra 矩阵快速幂
题意: 给出\(p=a+b\)和\(q=ab\),求\(a^n+b^n\). 分析: 这种题目关键还是在于构造矩阵: \(\begin{bmatrix} 0 & 1 \\ -(a+b) &am ...
- CodeForces 489F DP Special Matrices
首先统计一下前m行中,有x列1的个数为0,有y列1的个数为1. 设d(i, j)表示有i列1的个数为0,有j列1的个数为1,能到达这个状态的矩阵的个数. 则d(x, y) = 1 每一行都是两个1一起 ...
- Socketserver详解
Python3中的SocketServer socket并不能多并发,只能支持一个用户,socketserver 简化了编写网络服务程序的任务,socketserver是socket的在封装.sock ...
- Objective-C中的一些特殊的数据类型
nil nil和C语言的NULL相同,在objc/objc.h中定义.nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空). Nil 首字母大写的Nil和nil有一点不一样 ...
- javascript 内置日期转换方法
var d = new Date(); console.log(d); // 输出:Mon Nov 04 2013 21:50:33 GMT+0800 (中国标准时间) console.log(d.t ...
- STL学习笔记1--vector
C++STL(Standard Template Library)标准模板库是通用类模板和算法的集合.包含一些标准的数据结构的实现如queues(队列),lists(链表),stacks(栈)等.ST ...
- SVM用于线性回归
SVM用于线性回归 方法分析 在样本数据集()中,不是简单的离散值,而是连续值.如在线性回归中,预测房价.与线性回归类型,目标函数是正则平方误差函数: 在SVM回归算法中,目的是训练出超平面,采用作为 ...
- python踩坑系列——报错后修改了.py文件,但是依然报错
一开始.py文件中的函数名大小写错了,但是在终端是对的,报错: 'module' object has no attribute '某函数名' 后来就去修改.py文件.结果重新import该.py文件 ...
- Django创建并连接数据库(实现增删改查)--第二版
注意点一: url里面的地址,不只是html页面,准确说是views视图里面对应的函数方法 <!DOCTYPE html> <html lang="en"> ...