Written with StackEdit.

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≤2*10^5\),所有点的编号都在\(1..N\)的范围内, 边的权值\(≤10^9\)。

Solution

  • 第一问显然,两次\(dfs\)即可.
  • 关于第二问,各个最远点的\(LCA\)一定是在所有直径上的.
  • 所以两次\(dfs\)时记录所有的最远点,求出它们的\(LCA\)(熟练剖腹),两个\(LCA\)的深度差即为答案(可以感性理解一下).
#include<bits/stdc++.h>
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int MAXN=2e5+10;
int n;
int cnt=0,head[MAXN];
int nx[MAXN<<1],to[MAXN<<1],val[MAXN<<1];
LoveLive dis[MAXN];
int dep[MAXN],siz[MAXN],top[MAXN],Fa[MAXN],sons[MAXN];
inline void add(int u,int v,int w)
{
++cnt;
nx[cnt]=head[u];
to[cnt]=v;
val[cnt]=w;
head[u]=cnt;
}
void dfs1(int u,int fa)
{
Fa[u]=fa;
siz[u]=1;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v==fa)
continue;
dep[v]=dep[u]+1;
dis[v]=dis[u]+val[i];
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[sons[u]])
sons[u]=v;
}
}
void dfs2(int u,int tp,int fa)
{
top[u]=tp;
if(!sons[u])
return;
dfs2(sons[u],tp,u);
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v==fa || v==sons[u])
continue;
dfs2(v,v,u);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
x=Fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
void init(int rt)
{
memset(sons,0,sizeof sons);
dep[rt]=1;
dis[rt]=0;
}
vector<int> G;
int main()
{
n=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read(),w=read();
add(u,v,w);
add(v,u,w);
}
init(1);
dfs1(1,0);
dfs2(1,1,0);
LoveLive ans=0;
for(int i=1;i<=n;++i)
{
if(dis[i]>ans)
G.clear(),ans=dis[i];
if(ans==dis[i])
G.push_back(i);
}
int now=G[0];
int tot=G.size();
for(int i=1;i<tot;++i)
now=LCA(now,G[i]);
int lca1=now;
int rt=G[0];
ans=0;
init(rt);
dfs1(rt,0);
dfs2(rt,rt,0);
G.clear();
for(int i=1;i<=n;++i)
{
if(dis[i]>ans)
G.clear(),ans=dis[i];
if(ans==dis[i])
G.push_back(i);
}
printf("%lld\n",ans);
now=G[0];
tot=G.size();
for(int i=1;i<tot;++i)
now=LCA(now,G[i]);
int lca2=now;
printf("%d\n",abs(dep[lca1]-dep[lca2]));
return 0;
}

bzoj 3124 直径的更多相关文章

  1. Bzoj 3124: [Sdoi2013]直径 题解

    3124: [Sdoi2013]直径 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1222  Solved: 580[Submit][Status] ...

  2. bzoj 3124: [Sdoi2013]直径

    #include<cstdio> #include<iostream> #define M 400009 #define ll long long using namespac ...

  3. bzoj 3124 [Sdoi2013]直径(dfs)

    Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一 ...

  4. SDOI2013 R1 Day1

    目录 2018.3.22 Test 总结 T1 BZOJ.3122.[SDOI2013]随机数生成器(BSGS 等比数列) T2 BZOJ.3123.[SDOI2013]森林(主席树 启发式合并) T ...

  5. bzoj千题计划134:bzoj3124: [Sdoi2013]直径

    http://www.lydsy.com/JudgeOnline/problem.php?id=3124 第一问: dfs1.dfs2 dfs2中记录dis[i]表示点i距离最长链左端点的距离 第二问 ...

  6. 3124: [Sdoi2013]直径

    3124: [Sdoi2013]直径 https://www.lydsy.com/JudgeOnline/problem.php?id=3124 分析: 所有直径都经过的边,一定都是连续的一段.(画个 ...

  7. BZOJ 2282 & 树的直径

    SDOI2011的Dayx第2题 题意: 在树中找到一条权值和不超过S的链(为什么是链呢,因为题目中提到“使得路径的两端都是城市”,如果不是链那不就不止两端了吗——怎么这么机智的感觉...),使得不在 ...

  8. bzoj 2282 [Sdoi2011]消防(树的直径,二分)

    Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家 ...

  9. bzoj 1912 巡逻(树直径)

    Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...

随机推荐

  1. echo指令

    1.在Linux中echo命令用来在标准输出上显示一段字符,比如:echo "the echo command test!" 这个就会输出“the echo command tes ...

  2. import和import static的区别

    import static静态导入是JDK1.5中的新特性. 一般我们导入一个类都用 import 包名.类名; 而静态导入是这样:import static 包名.类名.*; 这里的多了个stati ...

  3. TCP的滑动窗口

    TCP发送方的窗口可以划分成四个部分: 1.已经发送并且确认的TCP段: 2.已经发送但是没有确认的TCP段: 3.未发送但是接收方准备接收的TCP段, 4.未发送并且接收方也为准备接受的TCP段. ...

  4. java 处理emoji表情信息转换为String

    2种方式实现: 注意:如果发现运行时java.lang.NoClassDefFoundError:异常就是缺少了jar包.添加对应的jar包就可以. 一.emoji-java-4.0.0.jar实现 ...

  5. JNIjw06

    1.VC6(CPP)的DLL代码: #include<stdio.h> #include "jniZ_JNIjw06.h" // 全局变量 jfieldID g_pro ...

  6. 初探UiAutomator2.0中使用Xpath定位元素

    J 今天的主题是讲一下在使用过程中遇到的一个问题,如何在UiAutomator2.0中使用Xpath定位元素? 背景 现在的app在打包成apk的时候都是有加固处理的,各种混淆加固,所以已经破坏了或扰 ...

  7. 入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 介绍 (一)

    现代的应用程序看起来像这样: 典型的交互操作包括: 浏览器与 web 应用程序进行通信 Web 应用程序与 web Api (有时是在他们自己的有时代表用户) 通信 基于浏览器的应用程序与 web A ...

  8. 在UIElement外面多套一层布局面板(Grid、StackPanel)的意义

    在一个UIElement或多个UIElement外面套上一层布局面板(Grid.StackPanel),可以起到统一管理作用(非重点关注):另外,更重要的是:可以起到扩大UIElement操作有效范围 ...

  9. js的onclick字符串参数的解决办法

    <a href='#' onclick='onedit(\""+ name + "\")';>编辑</a>" 一些写法实例~~ ...

  10. jenkins构建中的除零错误

    一. 除零错误(ZeroDivisionError) 今天在jenkins上运行接口自动化测试任务时,从控制台输出中看到了除零错误,大概是这样的 从上图中,通过分析,可以得出三个结论: 1. jenk ...