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 ...
随机推荐
- 【 android】When an app is installed on the external storage
When an app is installed on the external storage: The .apk file is saved to the external storage, bu ...
- 有关git clone 下载速度变慢的解决方法
使用提示:请注意一下,以下方法是在搭有梯子的情况下进行的,也就是说在有梯子的情况下,下载速度始终很慢,使用了以下方法用梯子下载达到正常速度,并没有尝试修复过后不用梯子下载. 所以,如果使用了以下方法, ...
- 素数筛选:HDU2710-Max Factor
Max Factor Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem ...
- 带有命名空间的xml解析,C#
前一段时间做花旗的接口,返回的xml格式是带有命名空间的,可是难倒了我,找了好久才找到解决办法,给大家分享下,少走弯路. 1,直接进入正题,先看一段带有命名空间的xml,这段xml大概的意思是,前面是 ...
- Oracle数据库的日常使用命令
1. 启动和关闭数据库 sqlplus /nolog; SQL >conn / as sysdba;(上面的两条命令相当于sqlplus ‘/as sysdba’) SQL >st ...
- tomcat6-servlet规范对接 与 ClassLoader隔离
之前写的一个ppt 搬到博客来
- python week08 并发编程之多线程--理论部分
一. 什么是线程 1.定义 线程就像一条工厂车间里的流水线,一个车间里可以用很多流水线,来执行生产每个零部件的任务. 所以车间可以看作是进程,流水线可以看作是线程.(进程是资源单位,线程是执行单位) ...
- 【LeetCode】Longest Common Prefix(最长公共前缀)
这道题是LeetCode里的第14道题. 题目描述: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["f ...
- Concept with HTTP API && RPC
RPC=Remote Produce Call 是一种技术的概念名词. HTTP是一种协议,RPC可以通过HTTP来实现,也可以通过Socket自己实现一套协议来实现.所以楼主可以换一个问法,为何RP ...
- c++中vector容器的功能及应用。
vector基本操作: 1.头文件 #include<vector>. 注:一定要加上using namespace std; 2.vector对象的创建: vector<int ...