BZOJ_3124_[Sdoi2013]直径_树形DP

Description

小Q最近学习了一些图论知识。根据课本,有如下定义。树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度。如果一棵树有N个节点,可以证明其有且仅有N-1 条边。 路径:一棵树上,任意两个节点之间最多有一条简单路径。我们用 dis(a,b)
表示点a和点b的路径上各边长度之和。称dis(a,b)为a、b两个节点间的距离。 
 直径:一棵树上,最长的路径为树的直径。树的直径可能不是唯一的。
现在小Q想知道,对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。

Input

第一行包含一个整数N,表示节点数。
接下来N-1行,每行三个整数a, b, c ,表示点 a和点b之间有一条长度为c
的无向边。

Output

共两行。第一行一个整数,表示直径的长度。第二行一个整数,表示被所有
直径经过的边的数量。

Sample Input

6
3 1 1000
1 4 10
4 2 100
4 5 50
4 6 100

Sample Output

1110
2

【样例说明】
直径共有两条,3 到2的路径和3到6的路径。这两条直径都经过边(3, 1)和边(1, 4)。

HINT

对于100%的测试数据:2≤N≤200000,所有点的编号都在1..N的范围内,
边的权值≤10^9。


边权非负,可以用一个基于贪心的方法求直径。

以1为根进行dfs,求出每个点到根的距离dis1,令rt1为最大的一个点。

以rt1为根就能拽出来一条直径rt1---rt2,求出每个点到根的距离dis2。

所求的那些边一定是连续的,如果不连续则中间的那个一定可以替代边上的边。

考虑dis2[i]=dis2[rt2]的那些点i,一定可以和rt1形成又一条直径,于是可以把i和rt2的lca一下的那些边抠掉。

然后反过来再做一遍就可以啦。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 200050
typedef long long ll;
int head[N],to[N<<1],nxt[N<<1],val[N<<1],cnt,n,fa[N],dep[N],f[25][N],dis3[N];
ll dis1[N],dis2[N];
int rt1,rt2;
inline void add(int u,int v,int w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
void dfs1(int x,int y) {
int i;
if(dis1[x]>dis1[rt1]) rt1=x;
for(i=head[x];i;i=nxt[i]) {
if(to[i]!=y) {
dis1[to[i]]=dis1[x]+val[i];
dfs1(to[i],x);
}
}
}
void dfs2(int x,int y) {
int i; fa[x]=y; f[0][x]=y;
if(dis2[x]>dis2[rt2]) rt2=x;
for(i=head[x];i;i=nxt[i]) {
if(to[i]!=y) {
dep[to[i]]=dep[x]+1;
dis2[to[i]]=dis2[x]+val[i];
dfs2(to[i],x);
}
}
}
int lca(int x,int y) {
if(dep[x]<dep[y]) swap(x,y);
int i;
for(i=20;i>=0;i--) {
if(f[i][x]&&dep[f[i][x]]>=dep[y]) x=f[i][x];
}
if(x==y) return x;
for(i=20;i>=0;i--) {
if(f[i][x]&&f[i][y]&&f[i][x]!=f[i][y]) x=f[i][x],y=f[i][y];
}
return f[0][x];
}
void dfs3(int x,int y) {
int i; f[0][x]=y;
for(i=head[x];i;i=nxt[i]) {
if(to[i]!=y) {
dep[to[i]]=dep[x]+1;
dis3[to[i]]=dis3[x]+val[i];
dfs3(to[i],x);
}
}
}
int main() {
scanf("%d",&n);
int i,x,y,z;
for(i=1;i<n;i++) {
scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z);
}
dfs1(1,0); dfs2(rt1,0);
int j;
for(i=1;(1<<i)<=n;i++) {
for(j=1;j<=n;j++) f[i][j]=f[i-1][f[i-1][j]];
}
int U=rt2;
for(i=1;i<=n;i++) if(dis2[i]==dis2[rt2]) U=lca(U,i);
memset(f,0,sizeof(f));
dfs3(rt2,0);
for(i=1;(1<<i)<=n;i++) {
for(j=1;j<=n;j++) f[i][j]=f[i-1][f[i-1][j]];
}
int D=rt1;
// printf("%d %d\n",rt1,rt2);
for(i=1;i<=n;i++) if(dis3[i]==dis3[rt1]) D=lca(D,i);
printf("%lld\n%d\n",dis2[rt2],dep[D]-dep[U]);
}

BZOJ_3124_[Sdoi2013]直径_树形DP的更多相关文章

  1. 2018.11.05 bzoj3124: [Sdoi2013]直径(树形dp)

    传送门 一道sbsbsb树形dpdpdp 第一问直接求树的直径. 考虑第二问问的边肯定在同一条直径上均是连续的. 因此我们将直径记下来. 然后对于直径上的每一个点,dpdpdp出以这个点为根的子树中不 ...

  2. BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

    BZOJ_1864_[Zjoi2006]三色二叉树_树形DP 题意: 分析:递归建树,然后DP,从子节点转移. 注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的.这样的话我们只需要知道当 ...

  3. BZOJ_3573_[Hnoi2014]米特运输_树形DP+hash

    BZOJ_3573_[Hnoi2014]米特运输_树形DP+hash 题意: 给你一棵树每个点有一个权值,要求修改最少的权值,使得每个节点的权值等于其儿子的权值和且儿子的权值都相等. 分析: 首先我们 ...

  4. B20J_4027_[HEOI2015]兔子与樱花_树形DP

    B20J_4027_[HEOI2015]兔子与樱花_树形DP 题意: 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编 ...

  5. BZOJ_1040_[ZJOI2008]骑士_树形DP

    BZOJ_1040_[ZJOI2008]骑士_树形DP 题意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪 ...

  6. BZOJ_1060_时态同步_树形DP

    BZOJ_1060_时态同步_树形DP 题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1060 分析:水水的树形DP. 用儿子的最大值更新父亲, ...

  7. BZOJ_1827_[Usaco2010 Mar]gather 奶牛大集会_树形DP

    BZOJ_1827_[Usaco2010 Mar]gather 奶牛大集会_树形DP 题意:Bessie正在计划一年一度的奶牛大集会,来自全国各地的奶牛将来参加这一次集会.当然,她会选择最方便的地点来 ...

  8. BZOJ_4726_[POI2017]Sabota?_树形DP

    BZOJ_4726_[POI2017]Sabota?_树形DP Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属 ...

  9. BZOJ_1304_[CQOI2009]叶子的染色_树形DP

    BZOJ_1304_[CQOI2009]叶子的染色_树形DP Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白 ...

随机推荐

  1. IP地址 网段的划分

    IP和子网掩码我们都知道,IP是由四段数字组成,在此,我们先来了解一下3类常用的IP A类IP段 0.0.0.0 到127.255.255.255  B类IP段 128.0.0.0 到191.255. ...

  2. GenericServlet 、Servlet和httpServler他们之间的关系

    1.GenericServlet类是所有Servlet类的祖先类. 2.HttpServlet类继承了GenericServlet类. 3.Servlet有两个非常重要的的对象,可以说是java we ...

  3. vs2013数据库连接对应的dll

    mysql for visual studio 1.1.1mysql connector net 6.3.9mysql connector/odbc 5.3

  4. Docker入门系列1:简介

    可以实现快速部署. 比如一台 16 核 32G 内存的虚拟机上,需要跑 500+ 个用户的应用(每个应用的功能可以认为是一个网站 + 一系列的 RESTful API),有两个事情很重要: 资源隔离: ...

  5. linux 上操作常用的命苦与出错的地方

    帮助信息 ./configure -help|grep mysql 出错提示安装libxml2 tar -zxvf libxml2xxxx.tar cd libxml2xxx ./configure ...

  6. A charge WIFI point base on airbase-ng+dhcp+lamp+wiwiz

    Make wifi as a hot point Make a script echo $0 $1 case $1 in "start") sleep 1 ifconfig wla ...

  7. spring事务和mysql的隔离级别

    mysql事务.mysql隔离级别.mysql锁.mysql数据一致性.Spring事务.Spring事务传播性之间的关系 一直有些模糊,整理一下.   mysql事务: 在mysql中,只有使用了I ...

  8. FI模块与SD、MM的接口配置方法

    [转自 http://blog.itpub.net/195776/viewspace-1023910/] 1 FI/SD 借口配置FI/SD通过tcode VKOA为billing设置过帐科目,用户可 ...

  9. 特殊例子--JavaScript代码实现图片循环滚动效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. 开发笔记--java.lang.OutOfMemoryError: PermGen space异常处理

    第一次到公司开发项目,比起之前的小项目来说这次的项目特别大,以至于运行之后出现了java.lang.OutOfMemoryError: PermGen space的异常,从字面意思上来看是内存溢出的原 ...