[BZOJ1999] 树网的核 [数据加强版] (树的直径)
传送门
如果只是想验证算法正确性这里是洛谷数据未加强版
Description
设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V, E分别表示结点与边的集合,W表示各边长度的集合,并设T有n个结点。 路径:树网中任何两结点a,b都存在唯一的一条简单路径,用d(a,b)表示以a,b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a,b)为a,b两结点间的距离。 一点v到一条路径P的距离为该点与P上的最近的结点的距离: d(v,P)=min{d(v,u),u为路径P上的结点}。 树网的直径:树网中最长的路径称为树网的直径。对于给定的树网T,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。 偏心距ECC(F):树网T中距路径F最远的结点到路径F的距离,即 。 任务:对于给定的树网T=(V, E,W)和非负整数s,求一个路径F,它是某直径上的一段路径(该路径两端均为树网中的结点),其长度不超过s(可以等于s),使偏心距ECC(F)最小。我们称这个路径为树网T=(V,E,W)的核(Core)。必要时,F可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但最小偏心距是唯一的。 下面的图给出了树网的一个实例。图中,A-B与A-C是两条直径,长度均为20。点W是树网的中心,EF边的长度为5。如果指定s=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为8。如果指定s=0(或s=1、s=2),则树网的核为结点F,偏心距为12。
Input
包含n行: 第1行,两个正整数n和s,中间用一个空格隔开。其中n为树网结点的个数,s为树网的核的长度的上界。设结点编号依次为1, 2, ..., n。 从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。 所给的数据都是正确的,不必检验。
Output
只有一个非负整数,为指定意义下的最小偏心距。
Sample Input
5 2
1 2 5
2 3 2
2 4 4
2 5 3
Sample Output
5
HINT
对于70%的数据,n<=200000
对于100%的数据:n<=500000, s<2^31, 所有权值<500
==============================================
似乎SPOJ上加强版的数据...
题解
好题啊好题
T了好几次,深度怀疑写的是不是O(n)算法,最后在各种改进下终于过了QAQ
题目要求最小偏心距,我们分析题意后发现
\(最小偏心距=max(max(dis(k,ij)),dis(i,S),dis(j,T))\)
其中ij表示一段直径上的、起点为i、长度<=s的最长路径
k为非直径上点,\(max(dis(k,ij))\) 表示距离ij最远的非直径点到ij的距离
\(dis(i,S)\)和\(dis(j,T)\)表示i和j到直径一端的距离
(所以\(dis(S,i)+dis(i,j)+dis(j,T)=dis(S,T)\))
然后用单调队列记录\(max(dis(k,ij))\)便可以O(n)跑了
不过我们再分析一下,发现其实不用单调队列qwq
由于直径有最长性,任何从S,i之间分叉离开直径的子树,其最远点到i的距离一定不会比S更远(否则这就不是直径)
这就说明 当ij中不包含点u时,\(dis(k,u)\)一定小于\(dis(i,S),dis(j,T)\)中的一个或两个,所以它一定不会被统计到ij的偏心距中去
这样的话我们只需记录\(max(dis(k,ST))\)的值,
如果\(max(dis(k,ST))\)在当前\(dis(k,ij)\)中,那么这个值有可能比\(dis(i,S),dis(j,T)\)大,统计到当前的偏心距中
如果\(max(dis(k,ST))\)不在当前\(dis(k,ij)\)中,那么所有dis(k,ij)都没有机会被统计,因为我们有上面的结论知道\(dis(i,S),dis(j,T)\)中一定有一个或两个比\(max(dis(k,ST))\)大那么也一定大于所有\(dis(k,ij)\)
所以只需求出\(max(dis(k,ST))\)之后就和之前讲的一样,只不过不用单调队列了
code:
//By Menteur_Hxy
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define C(i,a,b) for(register int i=(b);i>=(a);i--)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
#define add(a,b,c) nxt[++ecnt]=head[a],to[ecnt]=b,dis[ecnt]=c,head[a]=ecnt
#define insert(a,b,c) add(a,b,c),add(b,a,c)
using namespace std;
inline LL rd() {
LL x=0,fla=1; char c=' ';
while(c>'9'|| c<'0') {if(c=='-') fla=-fla; c=getchar();}
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*fla;
}
inline void out(LL x){
int a[25],wei=0;
if(x<0) putchar('-'),x=-x;
for(;x;x/=10) a[++wei]=x%10;
if(wei==0){ puts("0"); return;}
for(int j=wei;j>=1;--j) putchar('0'+a[j]);
putchar('\n');
}
const int N=500010;
int n,s,ecnt,rt,ret,len,md,r,mafa,ans=0x3f3f3f3f,S,T;
int nxt[N<<1],dis[N<<1],to[N<<1],head[N],nd[N],dep[N],sta[N];
int sd[N],td[N],fa[N];
bool inr[N];
inline void dfs(int u,int pre,int num) {
if(md<=dep[u]) rt=u,md=dep[u];
E(i,u) { int v=to[i];
if(v==pre) continue;
dep[v]=dep[u]+dis[i];
fa[v]=u;
dfs(v,u,num+1);
}
}
inline void dfs2(int u,int pre) {
if(dep[u]>md) md=dep[u];
E(i,u) { int v=to[i];
if(v==pre or inr[v]) continue;
dep[v]=dep[u]+dis[i];
dfs2(v,u);
}
}
int main() {
n=rd(),s=rd();
F(i,1,n-1) {int a=rd(),b=rd(),c=rd();insert(a,b,c);}
dfs(1,0,1); dep[rt]=0; S=rt; fa[S]=0;
dfs(rt,0,1); T=rt;
for(int i=T;i;i=fa[i]) sd[i]=dep[i],td[i]=md-sd[i],inr[i]=1;
int fla=0,ret;
for(int i=T;i;i=fa[i]) {
if(fla) ret=sd[i],sd[i]=td[i],td[i]=ret;
md=dep[i]=0,dfs2(i,0),mafa=max(mafa,md);
}
int t=T;
for(int i=T;i;i=fa[i]) { if(t==S) break;
while(td[fa[t]]-td[i]<=s&&fa[t]) t=fa[t];
ans=min(ans,max(mafa,max(td[i],sd[t])));
}
out(ans);
return 0;
}
[BZOJ1999] 树网的核 [数据加强版] (树的直径)的更多相关文章
- BZOJ1999 树网的核[数据加强版]
1999: [Noip2007]Core树网的核 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1214 Solved: 336[Submit][St ...
- 洛谷P1099 BZOJ1999 树网的核 [搜索,树的直径]
洛谷传送门,BZOJ传送门 树网的核 Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V ...
- [bzoj1999]树网的核
从下午坑到网上..noip的数据太弱,若干的地方写挂结果还随便过= = 最坑的就是网上有些题解没考虑周全... 第一步是找直径,用两次bfs(或者dfs,Linux下系统栈挺大的..)解决.找出其中一 ...
- 【BZOJ1999】树网的核
题目大意:题目过长,无法简单描述... 题解: 由于树网的核一定是树直径的一段,因此考虑先将直径取出,通过两次 BFS 即可.要求的东西是树上任意一点到这条取出的线段的距离的最大值,发现这个最大值有可 ...
- 5.19[bzoj树网的核]
围观了final,SJTU还是飞了,泽民同志劲啊! 膜拜归膜拜...回来开题 bzoj1999树网的核 最近就喜欢给自己找切不动的题...QAQ ok.....昨天在家里做了一个下午+晚上 又困&am ...
- 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列
题目描述 给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值.求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小. 输入 包含n行: 第1行,两个正整数n和s ...
- 【DFS好题】BZOJ1999- [Noip2007]Core树网的核(数据加强版)
NOIP的数据好水,一开始有好几个错结果NOIP数据就水过了?? [题目大意] 求无根树的直径上一段不超过S长的链,使得偏心距最小.具体概念见原题. [思路] 首先明确几个性质: (1)对于树中的任意 ...
- [BZOJ1999][codevs1167][Noip2007]Core树网的核
[BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...
- BZOJ1999或洛谷1099&BZOJ2282或洛谷2491 树网的核&[SDOI2011]消防
一道树的直径 树网的核 BZOJ原题链接 树网的核 洛谷原题链接 消防 BZOJ原题链接 消防 洛谷原题链接 一份代码四倍经验,爽 显然要先随便找一条直径,然后直接枚举核的两个端点,对每一次枚举的核遍 ...
随机推荐
- nginx配置文件使用
nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; 全局错误日志定义类型,[ debug | info | notice | warn | error | cri ...
- [MGR——Mysql的组复制之单主模式 ]详细搭建部署过程
1,关于MySQL Group Replication 基于组的复制(Group-basedReplication)是一种被使用在容错系统中的技术.Replication-group(复制组)是由 ...
- js动态创建表格------Day59
刚刚不知道怎么回事,CSDN博客一直打不开,就在博客园完毕了今天的记录,结果临关机,登录了下.发现又好了,就再多花个几分钟转下吧,也无论到底在意的是什么了,权当强迫症了... 前几天记录了动态的加入一 ...
- Fitnesse FIT的使用
FIT是fitnesse使用的默认的引擎(SLIM的使用在上一篇文章中说明),不需要特别声明即可使用执行表格测试,所有编写的fixture都需要继承Fit的Fitxture 编写测试用例前需要先声明c ...
- 扩展欧几里德 poj1061 青蛙的约会
扩展欧几里德很经典.可是也有时候挺难用的.一些东西一下子想不明确.. 于是来了一个逆天模板..仅仅要能列出Ax+By=C.就能解出x>=bound的一组解了~ LL exgcd(LL a, LL ...
- UVA1630 Folding 区间DP
Folding Description Bill is trying to compactly represent sequences of capital alphabetic characte ...
- 当使用Spring MVC @Valid对输入框进行验证的时候,可能会遇到以下的异常:Neither BindingResult nor plain target object for bean name ‘mybean’ available as request attribute
转自:https://www.cnblogs.com/wenhulu/p/5555457.html 当使用Spring MVC @Valid对输入框进行验证的时候,可能会遇到以下的异常: Neithe ...
- 中文分词--最大正向与逆向匹配算法python实现
最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描).例如:词典中 ...
- SwiftUI 官方教程(八)
8. 动态生成预览 接下来,我们会在 LandmarkList_Previews 中添加代码以在不同的设备尺寸上渲染列表.默认情况下,预览会以当前的 scheme 中设备的大小进行渲染.我们可以通过调 ...
- 对JVM还有什么不懂的?一文章带你深入浅出JVM!
本文跟大家聊聊JVM的内部结构,从组件中的多线程处理,JVM系统线程,局部变量数组等方面进行解析 JVM JVM = 类加载器(classloader) + 执行引擎(execution engine ...