hdoj3534(树形dp,求树的直径的条数)
题目链接:https://vjudge.net/problem/HDU-3534
题意:给出一棵树,求树上最长距离(直径),以及这样的距离的条数。
思路:如果只求直径,用两次dfs即可。但是现在要求最长距离的条数,用dp1[u]记录以u为根的子树中叶子结点到u的最长距离,dp2[u]表示最长距离的条数,这两个比较容易维护。dfs过程中更新答案,用ans1表示树上直径,ans2表示该直径的条数,当dp1[v]+w+dp1[u]>ans1时更新。
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=1e4+;
typedef long long LL;
int n,cnt,head[maxn];
LL ans1,ans2,dp1[maxn],dp2[maxn]; struct node{
int v,w,nex;
}edge[maxn<<]; void adde(int u,int v,int w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int u,int fa){
dp1[u]=,dp2[u]=;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v,w=edge[i].w;
if(v==fa) continue;
dfs(v,u);
int tmp=dp1[v]+w;
if(tmp+dp1[u]>ans1){
ans1=tmp+dp1[u];
ans2=dp2[u]*dp2[v];
}
else if(tmp+dp1[u]==ans1){
ans2+=dp2[u]*dp2[v];
}
if(tmp>dp1[u]){
dp1[u]=tmp;
dp2[u]=dp2[v];
}
else if(tmp==dp1[u]){
dp2[u]+=dp2[v];
}
}
} int main(){
while(~scanf("%d",&n)){
cnt=ans1=ans2=;
for(int i=;i<=n;++i)
head[i]=;
for(int i=;i<n;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
adde(v,u,w);
}
dfs(,);
printf("%lld %lld\n",ans1,ans2);
}
return ;
}
顺便附上只用两次dfs求直径的代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; typedef long long LL;
const int maxn=1e4+;
int n,cnt,head[maxn];
LL dp1[maxn],dp2[maxn]; struct node{
int v,w,nex;
}edge[maxn<<]; void adde(int u,int v,int w){
edge[++cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int u,int fa){
dp1[u]=;
int flag=;
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v,w=edge[i].w;
if(v==fa) continue;
flag=;
dfs(v,u);
if(dp1[v]+w>dp1[u]){
dp1[u]=dp1[v]+w;
dp2[u]=dp2[v];
}
}
if(!flag) dp2[u]=u;
} int main(){
while(~scanf("%d",&n)){
cnt=;
for(int i=;i<=n;++i)
head[i]=;
for(int i=;i<n;++i){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
adde(v,u,w);
}
dfs(,);
int tmp=dp2[];
dfs(tmp,);
printf("%lld\n",dp1[tmp]);
}
return ;
}
hdoj3534(树形dp,求树的直径的条数)的更多相关文章
- HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...
- 浅谈关于树形dp求树的直径问题
在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径. 求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这 ...
- 树形dp - 求树的直径
随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...
- 树形DP求树的直径
hdu4607 Park Visit Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 树形DP 学习笔记(树形DP、树的直径、树的重心)
前言:寒假讲过树形DP,这次再复习一下. -------------- 基本的树形DP 实现形式 树形DP的主要实现形式是$dfs$.这是因为树的特殊结构决定的——只有确定了儿子,才能决定父亲.划分阶 ...
- hdu2196 树形dp经典|树的直径
/* 两种做法 1.求出树直径v1,v2,那么有一个性质:任取一点u,树上到u距离最远的点必定是v1或v2 那么可以一次dfs求树v1 第二次求dis1[],求出所有点到v1的距离,同时求出v2 第三 ...
- codeforce 337D Book of Evil ----树形DP&bfs&树的直径
比较经典的老题 题目意思:给你一颗节点数为n的树,然后其中m个特殊点,再给你一个值d,问你在树中有多少个点到这m个点的距离都不大于d. 这题的写法有点像树的直径求法,先随便选择一个点(姑且设为点1)来 ...
- CS academy Growing Trees【模板】DP求树的直径
[题意概述] 给出一棵树,树上的边有两个值a和b,你可以在[0,limit]范围内选择一个整数delta,树上的边的权值为a+b*delta,现在问当delta为多少的时候树的直径最小.最小直径是多少 ...
- hdoj2196(树形dp,树的直径)
题目链接:https://vjudge.net/problem/HDU-2196 题意:给出一棵树,求每个结点可以到达的最远距离. 思路: 如果求得是树上最长距离,两次bfs就行.但这里求的是所有点的 ...
随机推荐
- mysql远程服务密码修改
GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY "root"; FLUSH PRIVILEGE ...
- Shell 04 字符串处理、正则表达式
一.字符串的处理 1.字符串截取 1.1 s{}表达式 ${变量名:起始位置:长度} (从0开始) n=number (n="number") echo ${#n} -- ...
- 路由器配置——DHCP+DHCP中继服务配置
一.实验目的:掌握DHCP服务基本配置及DHCP中继服务配置,实现全网互通 二.拓扑图: 三.具体步骤配置: (1)R1路由器配置: Router>enable --进入特权模式 Router ...
- bzoj 3545
bzoj 3555 离线版本 线段树合并 做法是将询问和边权都排序 给每个点建一棵线段树 然后边建mst边回答询问 每次合并两个连通块的时候 要将两个连通块的线段树合并起来 线段树合并部分code i ...
- c++ 数据类型长度
#include <iostream> using namespace std; int main() { cout << "char: " << ...
- while 循环 continue break 用法例子
py2 temp = "理解" # utf- 8 #解码, 需要指定原来的是什么编码 temp_unicode = temp.decode("utf-8") # ...
- 微信小程序之简单记账本开发记录(一)
下载并安装微信开发者工具 在选择开发记账本程序的时候犹豫着选择android studio还是微信小程序 最后选择了微信小程序,因其便利和快捷. 话不多说,第一步,下载并安装微信开发者工具.下面是教程 ...
- Java高并发下的 “单例模式”
前言:单例模式大家应该很熟悉了,我在这里就自己总结一下自己这段时间学到的单例相关的知识. 单例模式的目的:保证一个类只有单一的实例,也就是说你无法通过new来创建这个类的一个新实例. 单例模式的意义: ...
- JavaEE三大框架的整合
JavaEE三大框架的整合 ...
- Go语言 之TCP聊天室
服务端流程图如下: package main import ( "fmt" "net" ) // 客户端结构体 type Client struct { //用 ...