【BZOJ3242】【NOI2013】快餐店(动态规划)
【BZOJ3242】【NOI2013】快餐店(动态规划)
题面
题解
假设我们要做的是一棵树,那么答案显然是树的直径的一半。
证明?
假设树的直径是\(2d\),那么此时最远点的距离是\(d\)
假设存在一个点的距离大于\(d\),那么直径可以由这个点到达直径的一个端点拼出。
所以最远点距离为\(d\)。
现在的问题在基环树上。
可以用\(dp\)求出所有外向树上的直径以及能够一直向下延伸的最大深度\(f[i]\)。
显然最终在基环树上的答案一定只会经过基环树的一部分,
也就是如果从某条不在答案的路径上,把它断开,对于答案没有任何影响。
那么考虑枚举从哪个位置断开,然后维护一下最长链就好了。
我们把环上的点顺次放在一排,然后编号\(1..m\)
假设\(1->2->3->...->x\)的链长度为\(W[x]\)
那么最长链就是\(max(f[i]+f[j]+W[j]-W[i]),i\lt j\)
每次枚举断点,然后扫一遍求最大值,这样子的复杂度是\(O(n^2)\)的。
然后就是一堆奇奇怪怪的优化了,感觉我自己都说不清。
因为我是照着别人写的了 。。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 111111
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next,w;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
bool cir[MAX];
int p[MAX<<1],top,dep[MAX],fa[MAX],n;
ll f[MAX],ans,W[MAX<<1],Cir=1e18,pre1[MAX],pre2[MAX],l1[MAX],l2[MAX];
int Q[MAX<<1],H,T;
void findcir(int u,int ff)
{
dep[u]=dep[ff]+1;fa[u]=ff;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff)continue;
if(dep[v]&&dep[v]>dep[u])
{
for(int j=v;j!=u;j=fa[j])cir[j]=true,p[++top]=j;
p[++top]=u;cir[u]=true;continue;
}
if(!dep[v])findcir(v,u);
}
}
void dfs(int u,int ff)
{
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff||cir[v])continue;
dfs(v,u);ans=max(ans,f[u]+f[v]+e[i].w);
f[u]=max(f[u],f[v]+e[i].w);
}
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
{
int u=read(),v=read(),w=read();
Add(u,v,w);Add(v,u,w);
}
findcir(1,0);
for(int i=1;i<=top;++i)dfs(p[i],0);p[top+1]=p[1];
for(int i=1;i<=top;++i)
for(int j=h[p[i]];j;j=e[j].next)
if(e[j].v==p[i+1]){W[i]=e[j].w;break;}p[top+1]=0;
ll sum=0,mx=0;
for(int i=1;i<=top;++i)
{
sum+=W[i-1];pre1[i]=max(pre1[i-1],f[p[i]]+sum);
l1[i]=max(l1[i-1],f[p[i]]+mx+sum);
mx=max(mx,f[p[i]]-sum);
}
ll tot=W[top];W[top]=sum=mx=0;
for(int i=top;i;--i)
{
sum+=W[i];pre2[i]=max(pre2[i+1],f[p[i]]+sum);
l2[i]=max(l2[i+1],f[p[i]]+mx+sum);
mx=max(mx,f[p[i]]-sum);
}
Cir=l1[top];
for(int i=1;i<top;++i)
Cir=min(Cir,max(max(l1[i],l2[i+1]),pre1[i]+pre2[i+1]+tot));
ans=max(ans,Cir);
printf("%.1lf\n",ans/2.0);
return 0;
}
【BZOJ3242】【NOI2013】快餐店(动态规划)的更多相关文章
- bzoj3242 [Noi2013]快餐店
Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...
- BZOJ3242 [Noi2013]快餐店 【环套树 + 单调队列dp】
题目链接 BZOJ3242 题解 题意很清楚,找一点使得最远点最近 如果是一棵树,就是直径中点 现在套上了一个环,我们把环单独拿出来 先求出环上每个点外向树直径更新答案,并同时求出环上每个点外向的最远 ...
- bzoj 3242: [Noi2013]快餐店 章鱼图
3242: [Noi2013]快餐店 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 266 Solved: 140[Submit][Status] ...
- P1399 [NOI2013] 快餐店 方法记录
原题题面P1399 [NOI2013] 快餐店 题目描述 小 T 打算在城市 C 开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小 T 希望快餐店的地址选在离最 ...
- 动态规划:NOI2013 快餐店
Description 小 T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近 的地方. 快餐店的顾客分布 ...
- BZOJ3242/UOJ126 [Noi2013]快餐店
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- 3242: [Noi2013]快餐店 - BZOJ
Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...
- NOI2013 快餐店
http://uoj.ac/problem/126 总的来说,还是很容易想的,就是有点恶心. 首先,很明显只有一个环. 我们先找出这个环,给各棵树编号id[i],然后各棵树分别以环上的点为根,求出每个 ...
- bzoj 3242: [Noi2013]快餐店
Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...
- CF835F Roads in the Kingdom/UOJ126 NOI2013 快餐店 树的直径
传送门--CF 传送门--UOJ 题目要求基环树删掉环上的一条边得到的树的直径的最小值. 如果直接考虑删哪条边最优似乎不太可做,于是考虑另一种想法:枚举删掉的边并快速地求出当前的直径. 对于环上的点, ...
随机推荐
- 第六章P2P技术及应用
第六章P2P技术及应用 P2P技术在我们日常生活中非常实用,例如我们常用的QQ.PPLive.BitTorrent就是基于P2P技术研发.下面将本章中的重点内容进行归纳. 文章中的Why表示产生的背景 ...
- Python range() 函数用法
函数语法 range(start, stop[, step]) 参数说明: start: 计数从 start 开始.默认是从 0 开始.例如range(5)等价于range(0, 5); stop: ...
- python程序设计——面向对象程序设计:属性
python 3.x 的属性 可以将属性设置为 可读,可修改,可删除 # 只读属性,不允许修改和删除 class Test: def __init__(self,value): self.__valu ...
- Pairs Forming LCM LightOJ - 1236 素因子分解
Find the result of the following code: long long pairsFormLCM( int n ) { long long res = 0; fo ...
- DeepLearning - Overview of Sequence model
I have had a hard time trying to understand recurrent model. Compared to Ng's deep learning course, ...
- MVC与ajax【转】
首先我们要实现用户的注册功能.进入visual studio 点击文件->新建->项目->选择ASP.NET Web应用程序(.NET Framework)->选择的模板为MV ...
- pager-taglib2.0中文传参乱码问题
1.重现问题 在web项目中有时会用到pager-taglib来作为分页的标签,如上图红色框标识所示,当我们需要把页面参数保持的时候我们会在<pg:param />标签中把参数进行传递. ...
- 基于NABCD评论探路者团队贪吃蛇作品及改进建议
1.根据(不限于)NABCD评论作品的选题 N:随着人们生活压力越来越大,需要去去缓解压力,并且也需要不断进步,学习英语知识. A:它是基于java开发的一款软件,采用逐个吃字母,加长蛇身,增强记忆的 ...
- 20135313_exp5
课程:Java程序与设计 班级:1353 姓 名:吴子怡 学号:20135313 小组成员: 20135113肖昱 成绩: 指导教师:娄嘉鹏 实验日期:2 ...
- MOOK学习
课程选择及其理由 课程:c++程序设计 教师:魏英 学校:西北工业大学 总共:48讲 选择理由:我其实之前找了好几个,但由于小白,思考了下(迷茫,感觉好像都不错),然后看了一下大家都选择了西北工业大学 ...