传送门

基环树的题当然先考虑树上怎么搞,直接求个直径就完事了

现在多了个环,先把非环上的直径(设为 $ans$)和环上节点 $x$ 到叶子的最大距离(设为 $dis[x]$)求出来

考虑到对于某种最优的方案,环上一定有某条边完全不用走

所以可以枚举断哪个边然后暴力,显然会 $T$ 飞

考虑能够快速求出某条边断开后经过环的最大直径

预处理 $A[i],B[i],C[i],D[i]$

$A[i]$ 表示从环上某个固定的起点出发到达 $i$ 之前(包括 $i$) 的最长路径长度(这里路径包括到达叶子节点的路径)

这个可以通过维护起点到当前距离再加上我们之前求出的 $dis$ 得到

$B[i]$ 表示从环上那个固定的起点出发到达 $i$ 之前(包括 $i$)的节点中某两个叶子节点之间的最长距离

这个即为 $sum[i]-sum[j]+dis[i]+dis[j]$,其中 $sum[i]$ 表示起点到 $i$ 的环上路程

移项 $sum[i]+dis[i]+dis[j]-sum[j]$ ,动态维护当前 $dis[j]-sum[j]$ 的最大值即可

$C[i]$ 表示从环上终点(其实就是那个固定的起点的另一边的第一个节点)出发......(剩下的和 $A[i]$表示的是一样的)

$D[i]$ 同 $B[i]$ ,只是起点变成了终点,反过来了

那么预处理之后,枚举断边 $i$ (注意边 $i$ 连接 $i$ 和 $i+1$)那么 $t=max(B[i],D[i+1],A[i]+C[i+1]+w)$

其中 $w$ 是连接起点和终点的边的长度,那么 $A[i]+C[i+1]+w$ 其实就是跨过起点终点的距离

最后 $ans=max(ans,min(t))$,注意 $t$ 取最小值,因为断边是在最优方案下,肯定要取最小

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e5+;
const ll INF=1e18;
int n;
int fir[N],from[N<<],to[N<<],val[N<<],cntt;
inline void add(int a,int b,int c) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; val[cntt]=c; }
bool vis[N],ring[N],GG;
vector <int> st,wt;
vector <int> q,w;
void find(int x,int fa,int ww)
{
st.push_back(x); wt.push_back(ww); vis[x]=;
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(v==fa) continue;
if(vis[v])
{
while(st[st.size()-]!=v)
{
ring[st[st.size()-]]=;
q.push_back(st[st.size()-]);
w.push_back(wt[wt.size()-]);
st.pop_back(); wt.pop_back();
}
ring[v]=GG=; q.push_back(v);
w.push_back(val[i]); return;
}
find(v,x,val[i]); if(GG) return;
}
st.pop_back(); wt.pop_back();
}
ll dis[N],ans;
void dfs(int x,int fa)
{
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(ring[v]||v==fa) continue;
dfs(v,x); ans=max(ans,dis[x]+dis[v]+val[i]);
dis[x]=max(dis[x],dis[v]+val[i]);
}
}
ll A[N],B[N],C[N],D[N];
void solve()
{
find(,,); for(auto u: q) dfs(u,u);
ll sum=,mx=; int len=q.size();
A[]=B[]=dis[q[]];
for(int i=;i<len;i++)
{
mx=max(mx,dis[q[i-]]-sum); sum+=w[i-];
A[i]=max(A[i-],sum+dis[q[i]]);
B[i]=max(B[i-],mx+sum+dis[q[i]]);
}
sum=mx=; C[len-]=D[len-]=dis[q[len-]];
for(int i=len-;i>=;i--)
{
mx=max(mx,dis[q[i+]]-sum); sum+=w[i];
C[i]=max(C[i+],sum+dis[q[i]]);
D[i]=max(D[i+],mx+sum+dis[q[i]]);
}
ll res=B[len-];
for(int i=;i<len-;i++)
{
ll t=max(max(B[i],D[i+]), A[i]+C[i+]+w[len-] );
res=min(res,t);
}
ans=max(ans,res);
printf("%lld",ans>>);
ans& ? printf(".5\n") : printf(".0\n");
}
int main()
{
n=read(); int a,b,c;
for(int i=;i<=n;i++)
{
a=read(),b=read(),c=read();
add(a,b,c); add(b,a,c);
}
solve();
return ;
}

P1399 [NOI2013]快餐店的更多相关文章

  1. P1399 [NOI2013] 快餐店 方法记录

    原题题面P1399 [NOI2013] 快餐店 题目描述 小 T 打算在城市 C 开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小 T 希望快餐店的地址选在离最 ...

  2. luogu P1399 [NOI2013]快餐店

    传送门 注意到答案为这个基环树直径\(/2\) 因为是基环树,所以考虑把环拎出来.如果直径不过环上的边,那么可以在环上每个点下挂的子树内\(dfs\)求得.然后如果过环上的边,那么环上的部分也是一条链 ...

  3. bzoj 3242: [Noi2013]快餐店 章鱼图

    3242: [Noi2013]快餐店 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 266  Solved: 140[Submit][Status] ...

  4. bzoj3242 [Noi2013]快餐店

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

  5. 3242: [Noi2013]快餐店 - BZOJ

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

  6. 动态规划:NOI2013 快餐店

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

  7. NOI2013 快餐店

    http://uoj.ac/problem/126 总的来说,还是很容易想的,就是有点恶心. 首先,很明显只有一个环. 我们先找出这个环,给各棵树编号id[i],然后各棵树分别以环上的点为根,求出每个 ...

  8. bzoj 3242: [Noi2013]快餐店

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

  9. BZOJ3242/UOJ126 [Noi2013]快餐店

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

随机推荐

  1. 2002: [Hnoi2010]Bounce 弹飞绵羊(分块)

    2002: [Hnoi2010]Bounce 弹飞绵羊 时间限制: 10 Sec  内存限制: 259 MB 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他 ...

  2. Docker入门-数据挂载

    Docker数据管理 在容器中管理数据主要有两种方式: 数据卷(Volumes) 挂载主机目录(Bind mounts) 数据卷 数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很 ...

  3. Java连接MQTT服务-ws方式

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  4. spring的AOP基本原理

    一.什么是AOP AOP(Aspect Oriented Programming),意思是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP基于IoC基础,是对OOP ...

  5. 十四周学习总结&简易记事本

    学习总结: 一.JDBC: 1.JDBC提供里一套与平台无关的标准数据库操作接口和类,只要支持java的数据库厂商,所提供的数据库都可以以使用JDBC操作. 2.JDBC的主要操作类及接口: 3.JD ...

  6. centos6 yum安装mysql 5.6 (完整版)

    使用源代码编译安装mysql还是比较麻烦,一般来说设备安装时请网络同事临时开通linux上网,通过yum网络实现快速安装,或配置yum仓库进行内网统一安装. 通过网络快速安装过程如下 一.检查系统是否 ...

  7. BS架构和CS架构

    B:browser  浏览器 S:server       服务器 C:client        客户端 BS:浏览器和服务器的关系,通过浏览器来访问服务器.比如:新浪.百度.等等. 优点:只要有浏 ...

  8. 远程连接elasticsearch遇到的问题

    本文转自:https://blog.csdn.net/xuchuangqi/article/details/78989940 1.首先要远程连接就要把配置文件的network.host: 改为 net ...

  9. Delphi导出Excel的设置操作

    procedure CreatRepSheet(SheetName:String;PageSize,PageLay:Integer); {新建Excel工作簿.进行页面设置} begin {新建Exc ...

  10. Python学习之表的数据类型

    数据类型 数值类型 类型 大小 范围(有符号) 范围(无符号)unsigned约束 用途 TINYINT 1 字节 (-128,127) (0,255) 小整数值 SMALLINT 2 字节 (-32 ...