【题目链接】:http://noi.qz5z.com/viewtask.asp?id=b704 &&http://www.lydsy.com/JudgeOnline/problem.php?id=1999

【题意】



给你一棵树;

让你找出所有的直径;

并在这些直径上面选取连续的一段;

使得它的偏心距最小;

【题解】



这题有个思维量比较大的点就是;

多条直径,只要选取任意一条就好;

网上找到了很多分析;

感觉这个说得比较清楚吧;

/*
证明:首先,如图,如果ABCD和FBCE都是直径的话,则AB=FB,CD=CE(如果不然,可设AB>FB,则FBCE<ABCE,矛盾!)。这样,ABCE,FBCD也都是直径。我们给BC起个名字叫“公共段”。由连通性和路径的不唯一性,公共段必然存在。
考虑ecc的定义,路径的ecc是指所有的点到路径的距离的最大值。
核指的是直径上长度满足约束的ECC最小的子路经。假如根据直径ABCE算得的core是GHBI,路径GHBI的ecc就是max{BF,AG,DI, EI},这个最大值取到了最小。由于DC=EC,也就是说,如果路径和公共段有交集,公共段的一端上,不包含CORE的直径是可以任选的。换言之,如果max{BF,AG,DI, EI}取到了最小值,必有 max{BF,AG,ID}=max{BF,AG,DI, EI},此时用AB替换BF,则BF=AB>AG,ecc=max{BF,ID}。也就是说,如果路径和公共段有交集,实际计算max时,只需要计算路径在公共段上的部分的ecc,然后和公共段两端的路径长取一遍MAX就行了。
下面证明,使得ecc取到最小的core必然和公共段有交集。设没有交集,则必然有一条直径和这个core没有交集,此core的ecc就至少严格大于公共段长度+除去公共段的半条路径长度,然而,公共段上的点到其他点的最长距离,最大不会大于这个长度,这与ecc最小矛盾!
通过上面的论述,得出core只与公共段有关,也就是说引理成立。所以在计算时任选一条直径即可,}
*/

知道上面这个结论之后,瞬间压力就小了很多了;

再贪心一下;

可以想见,肯定是这段路径的长度越长越好;

(如果不是最长的,那么就会有一段多出来,所以感觉上是尽可能地长)

所以每次枚举这段路径的起点,终点的话可以根据s来确定,越长越好;

当然在枚举之前,先找出任意一条直径;然后把直径上的点标记一下;

然后从直径上的点开始进行dfs;在不经过直径的情况下,看看这个点最远能走多远;则这个长度就是这个点的偏心距了;

(整条直径的偏心距就是这个直径上的所有的点的偏心距的最大值->直径的偏心距的等价含义);

这个可以预处理出来;->设为mmax[n]

然后回到枚举那段

枚举了起点s,和终点t;

然后直径的左端点为l,右端点为r;

则这段路径s..t的偏心距为max(dis[l]-dis[s],dis[r]-dis[t],mmax[s..t]中的最大值);

(dis[x]是这段路径上的点x到直径的左端点l的距离);

因为在求mmax的时候没有考虑直径上的点,所以会漏掉这种情况.就是直径的左端点和右端点离这个核最远的情况.

这里s..t可以像窗口一样往右移动;

(保持前一次的右端点t不动,左端点右移,然后根据新的左端点调整右端点);

可以想到用单调队列来优化;

这里dis[l]-dis[s],dis[r]-dis[t]都是定值了,所以不用管;

直接维护mmax单调递减就好;

(求直径的话,随便从一个点开始dfs,找离他最远的点u1,然后从u1再重复上述过程,找到u2,则u1-u2就是一条直径);



【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define rei(x) scanf("%d",&x)
#define rel(x) scanf("%I64d",&x) typedef pair<int,int> pii;
typedef pair<LL,LL> pll; const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int MAXN = 5e5+100; struct abc
{
int nex,en,w;
}; int dis[MAXN],n,s,tot,fir[MAXN],path[MAXN],len,lmax[MAXN],rmax[MAXN],mmax[MAXN];
int dl[MAXN],l,r;
bool bo[MAXN];
abc bian[MAXN*2]; void add(int x,int y,int z)
{
bian[++tot].nex = fir[x];
fir[x] = tot;
bian[tot].en = y,bian[tot].w = z;
} void dfs(int x,int fa,int arr[])
{
for (int i = fir[x];i;i=bian[i].nex)
{
int y = bian[i].en; if (y==fa) continue; arr[y] = arr[x] + bian[i].w;
dfs(y,x,arr);
}
} bool get_path(int x,int aim,int fa)
{
if (x==aim)
{
path[++len] = x;
return true;
}
for (int i = fir[x];i;i=bian[i].nex)
{
int y = bian[i].en;
if (y==fa) continue; if (get_path(y,aim,x))
{
path[++len] = x;
return true;
}
}
return false;
} int gainecc(int x,int fa)
{
int ret = 0;
for (int i = fir[x];i;i = bian[i].nex)
{
int y = bian[i].en; if (bo[y] || y==fa) continue; ret = max(gainecc(y,x)+bian[i].w,ret);
}
return ret;
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);rei(s);
rep1(i,1,n-1)
{
int x,y,z;
rei(x);rei(y);rei(z); add(x,y,z),add(y,x,z);
} int q,w; dis[1] = 0;
dfs(1,0,dis); q = 1;
rep1(i,2,n)
if (dis[i]>dis[q])
q = i; dis[q] = 0;
dfs(q,0,dis); w = 1;
rep1(i,2,n)
if (dis[i]>dis[w])
w = i; get_path(w,q,0); rep1(i,1,len)
{
lmax[i] = dis[path[i]]-dis[q];
rmax[i] = dis[w]-dis[path[i]];
} rep1(i,1,len)
bo[path[i]] = true;
rep1(i,1,len)
mmax[path[i]] = gainecc(path[i],0); l = 1,r = 0;
int j = 0,ans = -1;
rep1(i,1,len)
{
while (j+1<=len && dis[path[j+1]]-dis[path[i]]<=s)
{
j++;
while (r>=l && mmax[path[j]]>=mmax[path[dl[r]]]) r--;
dl[++r] = j;
} while (dl[l] < i) l++; int cal = max(mmax[path[dl[l]]],max(lmax[i],rmax[j])); if (ans == -1 || cal < ans)
ans = cal;
} printf("%d\n",ans);
return 0;
}

【b704 && BZOJ 1999】树网的核的更多相关文章

  1. BZOJ 1099 树网的核

    题面 解题思路 搞了三个多小时.... noip时的数据很水,直接暴力n^3过. 我们考虑优化,首先可以贪心,我们要在直径上选肯定越插长越好,所以n^2其实就可以解决.但这还不够,根据直径的最长性,我 ...

  2. 洛谷P1099 BZOJ1999 树网的核 [搜索,树的直径]

    洛谷传送门,BZOJ传送门 树网的核 Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V ...

  3. 5.19[bzoj树网的核]

    围观了final,SJTU还是飞了,泽民同志劲啊! 膜拜归膜拜...回来开题 bzoj1999树网的核 最近就喜欢给自己找切不动的题...QAQ ok.....昨天在家里做了一个下午+晚上 又困&am ...

  4. [BZOJ1999][codevs1167][Noip2007]Core树网的核

    [BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...

  5. [bzoj1999]树网的核

    从下午坑到网上..noip的数据太弱,若干的地方写挂结果还随便过= = 最坑的就是网上有些题解没考虑周全... 第一步是找直径,用两次bfs(或者dfs,Linux下系统栈挺大的..)解决.找出其中一 ...

  6. BZOJ1999或洛谷1099&BZOJ2282或洛谷2491 树网的核&[SDOI2011]消防

    一道树的直径 树网的核 BZOJ原题链接 树网的核 洛谷原题链接 消防 BZOJ原题链接 消防 洛谷原题链接 一份代码四倍经验,爽 显然要先随便找一条直径,然后直接枚举核的两个端点,对每一次枚举的核遍 ...

  7. bzoj1999 / P1099 树网的核

    P1099 树网的核 (bzoj数据加强) 前置知识:树的直径 (并不想贴我的智障写法虽然快1倍但内存占用极大甚至在bzoj上MLE) 正常写法之一:用常规方法找到树的直径,在直径上用尺取法找一遍,再 ...

  8. BZOJ1999 树网的核[数据加强版]

    1999: [Noip2007]Core树网的核 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1214  Solved: 336[Submit][St ...

  9. 洛谷1099 [NOIP2007] 树网的核

    链接https://www.luogu.org/problemnew/show/P1099 题目描述 设T=(V,E,W)是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称TTT为 ...

随机推荐

  1. DOM事件机制

    前言 本文主要介绍DOM事件级别.DOM事件模型.事件流.事件代理和Event对象常见的应用,希望对你们有些帮助和启发! 本文首发地址为GitHub博客,写文章不易,请多多支持与关注! 一.DOM事件 ...

  2. 获得CSM(Certified Scrum Master)-价值驱动交付。

    2019年越来越多的企业开始实行敏捷转型,紧随时代潮流,学习最先进的科学管理方法,找到正确的人(团队),为企业交付高价值的产品服务. 导师Ethan ,培训的课程让人收益匪浅,活到老学到老,丰富的知识 ...

  3. MaxCompute推出面向开发者的专属版本,普惠大数据开发者

    3月20号,阿里云正式对外宣布推出MaxCompute产品的新规格-开发者版.MaxCompute开发者版是阿里云大数据计算服务发布的开发者专属版本.区别于原有的按量付费.按CU预付费规格,开发者版是 ...

  4. 【Django入坑之路】Django后台上传图片,以及前端的显示

    #setting配置: MEDIA_URL = "/media/" MEDIA_ROOT = os.path.join(BASE_DIR, "media") # ...

  5. AtCoder Regular Contest 094 D Worst Case【思维题】

    https://arc094.contest.atcoder.jp/tasks/arc094_b 题意: 在2次超多人的比赛中,你取得的成绩依次为第A名和第B名.一个人的成绩为a和b时,当且仅当ab& ...

  6. Validation异常:No validator could be found for constraint '.....' validating type 'java.lang.Integer'.

    javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'java ...

  7. Java练习 SDUT-3349_答答租车系统(面向对象综合练习)

    答答租车系统(面向对象综合练习) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 各位面向对象的小伙伴们,在学习了面向对 ...

  8. Java练习 SDUT-3339_计算长方形的周长和面积(类和对象)

    计算长方形的周长和面积(类和对象) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 设计一个长方形类Rect,计算长方形 ...

  9. tensorflow兼容处理 tensorflow.compat.v1

    https://www.wandouip.com/t5i183316/ 引言 原来引用过一个段子,这里还要再引用一次.是关于苹果的.大意是,苹果发布了新的开发语言Swift,有非常多优秀的特征,于是很 ...

  10. WPF动画之后属性值无法改变

    原文:WPF动画之后属性值无法改变         前一段时间使用WPF写2048游戏的时候,遇到下面的情形:使用按键对色块进行移动时,触发位置左边X和Y属性的DoubleAnimation动画,但是 ...