题目

题目描述

小 Q 最近学习了一些图论知识。根据课本,有如下定义。

树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度。如果一棵树有 N 个节点,可以证明其有且仅有 N-1 条边。

路径:一棵树上,任意两个节点之间最多有一条简单路径。我们用 dis(a,b)表示点 a 和点 b 的路径上各边长度之和。称 dis(a,b)为 a、b 两个节点间的距离。
直径:一棵树上,最长的路径为树的直径。树的直径可能不是唯一的。
现在小 Q 想知道,对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。


数据范围

对于 20%的测试数据:N≤100
对于 40%的测试数据:N≤1000
对于 70%的测试数据:N≤100000
对于 100%的测试数据:2≤N≤200000,所有点的编号都在 1..N 的范围内,边的权值≤10^9。
对于每个测试点,若输出文件的第一行与标准输出相同,则得到该测试点20%的分数,若输出文件的第二行与标准输出相同,则得到该测试点 80%的分数,两项可累加。
本题使用自定义校验器,为防止自定义校验器出错,即使你无法正确得出某一问的答案,也应在相应的位置随便输出一个数字。


题解

题意

给出一个树,求直径和有多少条边在所有的直径上

分析

对于直径,可以先随便找一个点(例如1),然后找到离它最远的那个点(x),然后再去找离x最远的那个点(y),那么x和y之间的距离就是直径

具体证明:传送门

然后把直径拉出来

对于直径上的每个点,记录从x到它的长度(设为len),并求出以它为根的子树距离它最远的点到它的长度(设为dis),并记录有多少个(设为num)

当len=dis的时候,答案直接减去deep(从0开始)后输出

若不是,当num>1,答案变为deep

Code

#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
long long head,to,next,val;
}a[400005];
long long n,i,x,y,z,root,s,ans,tot,deep[200005],f[200005],dis[200005],far[200005];
bool end,b[200005],bb[200005];
void add(long long x,long long y,long long z)
{
tot++;
a[tot].to=y;
a[tot].val=z;
a[tot].next=a[x].head;
a[x].head=tot;
}
void get(long long now,long long fa)
{
long long i,x;
for (i=a[now].head;i;i=a[i].next)
{
x=a[i].to;
if (x!=fa)
{
dis[x]=dis[now]+a[i].val;
get(x,now);
}
}
}
void dfs1(long long now)
{
long long i;
for (i=a[now].head;i;i=a[i].next)
{
long long x=a[i].to;
if (x!=f[now])
{
f[x]=now;
deep[x]=deep[now]+1;
dis[x]=dis[now]+a[i].val;
dfs1(x);
}
}
}
void dfs2(long long now)
{
if (end==true) return;
long long i,x,num;
long long mx;
bool bz;
num=0;
mx=-1;
bz=false;
for (i=a[now].head;i;i=a[i].next)
{
x=a[i].to;
if (x==f[now]) continue;
dfs2(x);
if (far[x]>=mx)
{
if (far[x]>mx)
{
mx=far[x];
num=1;
}
else num++;
}
if (far[x]-dis[now]==dis[now]) bz=true;
}
if (end==true) return;
if (b[now]==true)
{
if (bz==true)
{
ans-=deep[now]-1;
if (ans<0) ans=0;
printf("%lld\n",ans);
end=true;
return;
}
else
{
if (num>1) ans=deep[now]-1;
}
}
if (mx<dis[now]) mx=dis[now];
far[now]=mx;
}
int main()
{
scanf("%lld",&n);
for (i=1;i<n;i++)
{
scanf("%lld%lld%lld",&x,&y,&z);
add(x,y,z);
add(y,x,z);
}
get(1,0);
root=1;
for (i=2;i<=n;i++)
if (dis[i]>dis[root]) root=i;
memset(deep,0,sizeof(deep));
memset(f,0,sizeof(f));
memset(dis,0,sizeof(dis));
deep[root]=1;
f[root]=0;
bb[root]=true;
dfs1(root);
for (i=1;i<=n;i++)
if (dis[i]>dis[s]) s=i;
printf("%lld\n",dis[s]);
ans=deep[s]-1;
x=s;
while (x!=root)
{
b[x]=true;
x=f[x];
}
dfs2(root);
if (end==false) printf("%lld\n",ans);
return 0;
}

【SDOI2013】JZOJ8月3日提高组T4 直径的更多相关文章

  1. JZOJ8月15日提高组反思——2020年暑假终结篇

    JZOJ8月15日提高组反思--2020年暑假终结篇 T1 仙人掌最短路 抱歉我只会最短路 仙人掌是啥? 听说是缩点+\(LCA\) 最短路30 T2 直接暴力计算 正解\(DP\) \(amazin ...

  2. JZOJ8月4日提高组反思

    JZOJ8月4日提高组反思 被一堆2018&2019&2020的巨佬暴打 又是愉快的爆0的一天呢 T1 看了看题 没想法 暴力走起 求个质因数呀,二分呀-- 然后就炸了 正解预处理加二 ...

  3. JZOJ8月10日提高组反思

    JZOJ8月10日提高组反思 T1 没想到怎么打 就去打暴力了 本来想拿个30不错了 结果\(AC\)了 话说回来,数据也挺小的 T2 不AC便爆0 就一个数据点 给不给打暴力的人活了 正解是状压DP ...

  4. JZOJ2020年8月11日提高组T4 景点中心

    JZOJ2020年8月11日提高组T4 景点中心 题目 Description 话说宁波市的中小学生在镇海中学参加计算机程序设计比赛,比赛之余,他们在镇海中学的各个景点参观.镇海中学共有n个景点,每个 ...

  5. 【GDKOI2014】JZOJ2020年8月13日提高组T4 内存分配

    [GDKOI2014]JZOJ2020年8月13日提高组T4 内存分配 题目 Description Input Output 输出m行,每行一个整数,代表输入中每次程序变化后系统所需要的空闲内存单位 ...

  6. 【NOIP2015模拟11.5】JZOJ8月5日提高组T2 Lucas的数列

    [NOIP2015模拟11.5]JZOJ8月5日提高组T2 Lucas的数列 题目 PS:\(n*n*T*T<=10^{18}\)而不是\(10^1*8\) 题解 题意: 给出\(n\)个元素的 ...

  7. 【NOIP2015模拟11.5】JZOJ8月5日提高组T1 俄罗斯套娃

    [NOIP2015模拟11.5]JZOJ8月5日提高组T1 俄罗斯套娃 题目 题解 题意就是说 将1~\(n\)排列,问有多少种方案使得序列的逆序对个数小于\(k\) 很容易想到DP 设\(f[i][ ...

  8. JZOJ8月5日提高组反思

    JZOJ8月5日提高组反思 再次炸了 虽然不是爆0 但也没差多少-- T1 想的DP 然后就打了 一开始是只能拿60的 后来想到了用前缀和优化 然后打完交了 最后一分钟测了一下空间 爆了 就赶紧把数组 ...

  9. 【NOIP2015模拟11.2晚】JZOJ8月4日提高组T2 我的天

    [NOIP2015模拟11.2晚]JZOJ8月4日提高组T2 我的天 题目 很久很以前,有一个古老的村庄--xiba村,村子里生活着n+1个村民,但由于历届村长恐怖而且黑暗的魔法统治下,村民们各自过着 ...

随机推荐

  1. [Luogu P4124] [CQOI2016]手机号码 (数位DP)

    题面 传送门:洛咕 Solution 感谢神仙@lizbaka的教学 这题是数位DP的非常非常模板的题目,只是状态有点多 . 这题我使用记忆化搜索实现的 中国有句古话说的好,有多少个要求就设多少个状态 ...

  2. 【SpringBoot】02.编写HelloWorld

    1.编写一个返回HelloWorld的Controller @Controller public class HelloWorld { @ResponseBody @RequestMapping(&q ...

  3. 腾讯云对象存储COS新品发布——智能分层存储,自动优化您的存储成本

    近日,腾讯云正式发布对象存储新品--智能分层存储,能够根据用户数据的访问模式,自动地转换数据的冷热层级,为用户提供与标准存储一致的低延迟和高吞吐的产品体验,同时具有更低的存储成本. 熟悉数据存储的用户 ...

  4. Java实现FTP跨服务器文件操作

    在过去的几年工作中,曾经多次需要把文件上传到单独的服务器,而程序是在单独的服务器上部署的,在进行文件操作的时候就需要跨服务器进行操作包括:文件上传.文件下载.文件删除等.跨服务器文件操作一般是需要FT ...

  5. 虚拟机vbox给vdi增加容量到16G后的一系列操作

    虚拟机vbox给vdi增加容量到16G后的一系列操作windows 下:cmdVbox/bin下1.#VBoxManage modifyhd "cloned.vdi" --resi ...

  6. Css gray 无法覆盖IE10

    网站变灰这个效果很常见,在我这里暂时没有找到最优解决方式, 先把今天的研究结果记录一下. 第一种方案 : 对所有静态资源文件进行灰度处理,得到新一个资源目录,例如asset_ori 原始资源    a ...

  7. binary hacks读数笔记(readelf基本命令)

    一.首先对readelf常用的参数进行简单说明: readelf命令是Linux下的分析ELF文件的命令,这个命令在分析ELF文件格式时非常有用,下面以ELF格式可执行文件test为例详细介绍: 1. ...

  8. centos7安装数据库 (系统包含预装环境mariadb)

    查看系统是否安装了MySQL,有些没安装但是有路径,那是因为系统安装了mariadb-libs,对应的配置文件目录:/etc/my.cnf(下面就根据mariadb来安装mysql) 查看系统预装ma ...

  9. JAVA SE——集合框架

    1.首先根据业务场景选择哪种集合类型. set(无序,并且不包含重复元素),list(有序,并且允许重复元素),map(key-value,)

  10. 面试中AOP这样说,面试官只有一个字:服!