如果是树,那么一定选择树的直径的中点

套了个环?裸的想法显然是断开环,然后求所有树的直径的最小值

环套树dp的一般思路,先把环放到根,把环上点下面的子树dp出来,然后再处理环上的情况

设f[i]表示以i为根的子树向下延伸的最长链长度

我们把环上的点扩展一倍,用前缀和维护环上的边权

依次枚举断点,则对直径影响就是max(s[j]-s[i]+f[i]+f[j])

分别维护max(s[j]+f[j])和max(f[i]-s[i])

注意i≠j,所以我们还要维护一个次小值

 type node=record
po,next,num:longint;
end;
link=record
loc:longint;
mx:int64;
end; var tree:array[..*,..] of link;
e:array[..] of node;
cut:array[..] of boolean;
a,b,p,fa:array[..] of longint;
v:array[..] of boolean;
f,s:array[..] of int64;
i,len,n,t,x,y,z:longint;
ll,ans,lin:int64;
l1,l2,tp:link; function max(a,b:int64):int64;
begin
if a>b then exit(a) else exit(b);
end; function min(a,b:int64):int64;
begin
if a>b then exit(b) else exit(a);
end; procedure add(x,y,z:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
e[len].num:=z;
p[x]:=len;
end; procedure find(x:longint);
var i,y,h:longint;
begin
i:=p[x];
while i<>- do
begin
y:=e[i].po;
if not cut[i] then
begin
if fa[y]<> then
begin
h:=x;
while h<>y do
begin
inc(t);
a[t]:=h;
b[t]:=f[h];
h:=fa[h];
end;
inc(t);
a[t]:=h;
b[t]:=e[i].num;
break;
end
else begin
cut[i]:=true;
cut[i xor ]:=true;
fa[y]:=x;
f[y]:=e[i].num;
find(y);
end;
end;
if t<> then break;
i:=e[i].next;
end;
end; procedure dfs(x:longint);
var i,y:longint;
begin
v[x]:=true;
f[x]:=;
i:=p[x];
while i<>- do
begin
y:=e[i].po;
if not v[y] then
begin
dfs(y);
lin:=max(lin,f[y]+f[x]+e[i].num);
f[x]:=max(f[x],f[y]+e[i].num);
end;
i:=e[i].next;
end;
end; procedure update(var c:link; a:link; b:link);
begin
c.mx:=a.mx;
c.loc:=a.loc;
if c.mx<b.mx then
begin
c.loc:=b.loc;
c.mx:=b.mx;
end;
end; procedure build(i,l,r:longint);
var m:longint;
begin
if l=r then
begin
tree[i,].mx:=f[a[l]]+s[l];
tree[i,].loc:=l;
tree[i,].mx:=f[a[l]]-s[l];
tree[i,].loc:=l;
end
else begin
m:=(l+r) shr ;
build(i*,l,m);
build(i*+,m+,r);
update(tree[i,],tree[i*,],tree[i*+,]);
update(tree[i,],tree[i*,],tree[i*+,]);
end;
end; function ask(i,l,r,w,x,y:longint):link;
var m:longint;
s,s1,s2:link;
begin
if (x<=l) and (y>=r) then exit(tree[i,w])
else begin
m:=(l+r) shr ;
if x>m then exit(ask(i*+,m+,r,w,x,y));
if y<=m then exit(ask(i*,l,m,w,x,y));
s1:=ask(i*,l,m,w,x,y);
s2:=ask(i*+,m+,r,w,x,y);
update(s,s1,s2);
exit(s);
end;
end; begin
len:=-;
fillchar(p,sizeof(p),);
readln(n);
for i:= to n do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
fa[]:=-;
find();
for i:= to t do
begin
v[a[i]]:=true;
a[i+t]:=a[i];
b[i+t]:=b[i];
end;
for i:= to *t do
s[i]:=s[i-]+b[i-];
for i:= to t do
dfs(a[i]);
build(,,*t);
ans:=;
for i:= to t do
begin
l1:=ask(,,*t,,i+,i+t);
l2:=ask(,,*t,,i+,i+t);
if l1.loc=l2.loc then
begin
ll:=;
if l1.loc>i+ then
begin
tp:=ask(,,*t,,i+,l1.loc-);
ll:=max(ll,l1.mx+tp.mx);
end;
if l2.loc<i+t then
begin
tp:=ask(,,*t,,l2.loc+,i+t);
ll:=max(ll,l2.mx+tp.mx);
end;
ans:=min(ans,max(ll,lin));
end
else ans:=min(ans,max(l1.mx+l2.mx,lin));
end;
writeln(ans/::);
end.

bzoj3242的更多相关文章

  1. 【BZOJ3242】【NOI2013】快餐店(动态规划)

    [BZOJ3242][NOI2013]快餐店(动态规划) 题面 BZOJ 题解 假设我们要做的是一棵树,那么答案显然是树的直径的一半. 证明? 假设树的直径是\(2d\),那么此时最远点的距离是\(d ...

  2. BZOJ3242 [Noi2013]快餐店 【环套树 + 单调队列dp】

    题目链接 BZOJ3242 题解 题意很清楚,找一点使得最远点最近 如果是一棵树,就是直径中点 现在套上了一个环,我们把环单独拿出来 先求出环上每个点外向树直径更新答案,并同时求出环上每个点外向的最远 ...

  3. 【BZOJ3242】【UOJ#126】【NOI2013】快餐店

    NOI都是这种难度的题怎么玩嘛QAQ 原题: 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. ...

  4. BZOJ3242/UOJ126 [Noi2013]快餐店

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  5. bzoj3242 [Noi2013]快餐店

    Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...

  6. BZOJ3242 快餐店

    原题传送门 题意 给定一个n条边n个点的连通图,求该图的某一点在该图距离最远的点距离它的距离的最小值. 题解 显然,答案是\(\frac {原图直径}{2}\). 本体的图有 \(n\) 个点 \(n ...

  7. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

随机推荐

  1. UIScrollView显示超出屏幕大小的内容

    1:UIScrollView在初始化的时候可以指定frame,它的frame和其他控件不太一样的地方是: 它的frame指的的“可视大小”,也就是我们指定多大的frame来看一张图片,当然最大就是屏幕 ...

  2. GitHub error “Failed to get HEAD”

    cd /要提交的文件的文件夹下    比如要提交一个名为  demo的  程序, 那么先进入demo 的文件夹里面  然后  进行以下两步 git init  (有时这个是不必要的,因为xcode 自 ...

  3. Careercup - Facebook面试题 - 4907555595747328

    2014-05-02 07:49 题目链接 原题: Given a set of n points (coordinate in 2d plane) within a rectangular spac ...

  4. mysql注入绕过的一些技巧

    虽然mysql + php的开发中可以使用pdo中,但是有些老久的程序没有使用,或其他原因 1.注释绕过 select/*comment*/user/*zzsdsdsf*/from mysql.use ...

  5. MapInfo格式转arggis格式

    1. 下载MapInfo 11.0 2. 打开工具里的转换工具 3. 选择数据源和结果文件夹(目录中不能包含中文) 4. 转换成功.

  6. oracle 插入timestamp

    示例: insert into tpurview(IPURVIEWID,CPURVIEWNAME,COPERATENAME,IPARENTID,DADDTIME,DEDITTIME,CADDUSER, ...

  7. 使用静态变量的方法求n!

    下面的程序可以输出1-5的阶乘值,如果需要把5改为n,则可求出1-n的阶乘值. void main() { setvbuf(stdout,NULL,_IONBF,); int fac(int n); ...

  8. vc6命令行编译工程方法

    查vc++ 6.0 的 msdn找到下面的命令: msdev FileName [/MAKE "ProjectName – ConfigName | ALL"] [/REBUILD ...

  9. 山寨小小军团开发笔记 之 Arrow Projectile

    好久没怎么更新博客了,今天抽空来一篇,讨论一下弓箭的轨迹生成. 一.原理 弓箭的轨迹本质就是一个数学问题,使用一个 bezier 曲线公式就可以插值生成.得到轨迹后,做一个lookAt就可以了. 二. ...

  10. hashtable用法

    import java.util.Hashtable; public class HashTable { public static void main (String[] args) { Hasht ...