题目链接:快餐店

  震惊!某ZZ选手此题调了一天竟是因为……>>点击查看

  一般碰到这种基环树的题都要先想想树上怎么做。这道题如果是在树上的话……好像求一遍直径就做完了?答案就是直径长度的一半……

  然后我们来考虑一下基环树上的情况。假设我们选中了一个位置\(u\)作为快餐店,那么环上的有一条边是没有用的,也就是说\(u\)到其它所有点的最短路都不会经过这条边。于是,我们就可以枚举删掉环上每条边,就需要快速统计剩下这棵树的直径。如果这课树的直径没有经过环上的边,那么我们是可以通过预处理环上每棵树的直径来得到的。于是,我们接下来只考虑直径经过换上的边的情况。

  为了方便讲述,假设环上的点的编号为\(1\)到\(m\),\(1\)到\(x\)的边权和为\(w_x\)。首先,我们需要预处理环上每个点\(u\)为根往下的最长链\(f_u\)。然后,我们其实预处理几个数组即可(这里只考虑前缀),包括\(pre_i\),表示环上只用\([1,i]\)这些点组成的最长的链。由于\(pre_i=\max\{f_u+f_v+w_u-w_v\}(u>v)\),所以我们还需要维护一下\(f_x+w_x\),\(f_x-w_x\)的前缀最大值,然后每次更新即可。注意为了避免选出了两个重复的点,可以每次使用\(f_u+w_u+\max\{f_v-w_v\}(v<u)\)和\(pre_{u-1}\)来更新\(pre_u\)。类似的可以对后缀求出对应的数组。

  然后,我们在枚举环上断哪条边的时候只需要分三种情况讨论即可。假设我们断了边\((u,u+1)\),那么假设环上最优的两个点为\(i,j(i<j)\),那么要么\(1 \le i < j \le u\),要么\(u+1 \le i < j \le m\),还有\(1\le i \le u\)且\(u+1\le j \le m\)。分别用我们预处理出来的结果算出来,取个\(\max\)就是直径。最后把所有直径的\(\min\)和不过环的直径取个\(\max\)就是最终答案的两倍。

  然后我递归的时候函数名打错了……然后就到了另外一个函数里面去了……然后一天就这么过去了(捂脸

  你不要说我开头那个链接是在骗你吗……你看这里不是讲了原因么→_→

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
#define maxn 100010
#define maxm 200010
#define INF (1LL<<60) using namespace std;
typedef long long llg; int head[maxn],next[maxm],to[maxm],c[maxm],tt;
int n,m,fa[maxn],dfn[maxn],a[maxn];
llg dep[maxn],ans,f[maxn],b[maxn];
llg su[maxn],pr[maxn],qi[maxn][2],ho[maxn][2];
bool vis[maxn]; int getint(){
int w=0,q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') q=1,c=getchar();
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} void link(int x,int y){
to[++tt]=y;next[tt]=head[x];head[x]=tt;
to[++tt]=x;next[tt]=head[y];head[y]=tt;
c[tt-1]=c[tt]=getint();
} void work(int rt,int u){
while(u!=fa[rt]){
a[++m]=u; vis[u]=1; u=fa[u];
b[m+1]=dep[a[m]]-dep[u];
}
for(int i=1;i<=m;i++) b[i]+=b[i-1];
} void dfs(int u){
dfn[u]=++tt;
for(int i=head[u],v;v=to[i],i;i=next[i])
if(v!=fa[u] && !dfn[v]){
dep[v]=dep[u]+c[i];
fa[v]=u,dfs(v);
}
for(int i=head[u],v;v=to[i],i;i=next[i])
if(fa[v]!=u && dfn[v]>dfn[u]) b[1]=c[i],work(u,v);
} void dp(int u){
vis[u]=1;
for(int i=head[u],v;v=to[i],i;i=next[i])
if(!vis[v]){
dp(v); ans=max(ans,f[u]+f[v]+c[i]);
f[u]=max(f[u],f[v]+c[i]);
}
} void solve(){
qi[0][0]=ho[m+1][0]=pr[0]=-INF;
qi[0][1]=ho[m+1][1]=su[m+1]=-INF;
for(int i=1,u;u=a[i],i<=m;i++){
qi[i][0]=max(qi[i-1][0],f[u]+b[i]-b[1]);
qi[i][1]=max(qi[i-1][1],f[u]-b[i]+b[1]);
pr[i]=max(pr[i-1],f[u]+b[i]-b[1]+qi[i-1][1]);
}
for(int i=m,u;u=a[i],i>=1;i--){
ho[i][0]=max(ho[i+1][0],f[u]-b[i]+b[m]);
ho[i][1]=max(ho[i+1][1],f[u]+b[i]-b[m]);
su[i]=max(su[i+1],f[u]-b[i]+b[m]+ho[i+1][1]);
}
llg g=pr[m],now=0;
for(int i=1;i<m;i++){
now=b[1]+qi[i][0]+ho[i+1][0];
now=max(now,max(pr[i],su[i+1]));
g=min(g,now);
}
ans=max(ans,g);
} int main(){
File("a");
n=getint();
for(int i=1;i<=n;i++) link(getint(),getint());
tt=0; dfs(1);
for(int i=1;i<=m;i++) dp(a[i]);
solve();
printf("%.1lf",ans/2.0);
return 0;
}

  BZOJ提交网址:BZOJ 3242 快餐店

UOJ #126 【NOI2013】 快餐店的更多相关文章

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

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

  2. [UOJ#122][NOI2013]树的计数

    [UOJ#122][NOI2013]树的计数 试题描述 我们知道一棵有根树可以进行深度优先遍历(DFS)以及广度优先遍历(BFS)来生成这棵树的 DFS 序以及 BFS 序.两棵不同的树的 DFS 序 ...

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

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

  4. UOJ#126【NOI2013】快餐店

    [NOI2013]快餐店 链接:http://uoj.ac/problem/126 YY了一个线段树+类旋转卡壳的算法.骗了55分.还比不上$O(n^2)$暴力T^T 题目实际上是要找一条链的两个端点 ...

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

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

  6. 【BZOJ 3242】【UOJ #126】【CodeVS 3047】【NOI 2013】快餐店

    http://www.lydsy.com/JudgeOnline/problem.php?id=3242 http://uoj.ac/problem/126 http://codevs.cn/prob ...

  7. NOI2013 快餐店

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

  8. 【uoj126】 NOI2013—快餐店

    http://uoj.ac/problem/126 (题目链接) 题意 求基环树直径. Solution zz选手迟早退役,唉,右转题解→_→:LCF 细节 拓扑排序的时候度数为0时入队.我在想什么w ...

  9. bzoj3242 [Noi2013]快餐店

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

随机推荐

  1. CHAPTER 38 Reading ‘the Book of Life’ The Human Genome Project 第38章 阅读生命之书 人体基因组计划

    CHAPTER 38 Reading ‘the Book of Life’ The Human Genome Project 第38章 阅读生命之书 人体基因组计划 Humans have about ...

  2. MyCat安装与测试教程 超详细!

    MyCat安装与测试教程 超详细! MyCat基础知识 一.什么是MYCAT? 1. 一个彻底开源的,面向企业应用开发的大数据库集群 2. 支持事务.ACID.可以替代MySQL的加强版数据库 3. ...

  3. Codeblocks自动代码格式化快捷键(自带)

    代码区域右击 点format use AStyle 估计也就是考试竞赛逼着用这个

  4. access和MySQL mssql

    Access.MSSQL.MYSQL数据库之间有什么区别?     Access数据库.MSSQL数据库.MYSQL数据库之间有什么区别?        不少企业和个人站长在网站制作时,会对数据库的概 ...

  5. chattr和lsattr命令详解

    基础命令学习目录首页 原文链接:http://www.ha97.com/5172.html PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chat ...

  6. 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结

    将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...

  7. 三维空间中xoy平面上特定抛物线的正等测投影解析解的一种求法

    背景 背景:为锻炼代同学,老师给了她一个反向工程微信"跳一跳"小游戏的任务,希望做一个一样的出来.跳一跳中,有方块,有小人,小人站在方块上. 这个游戏的玩法是,用手指按住手机屏幕, ...

  8. Daily Scrum 11.10

    今日完成任务: 1.加入更改头像功能 2.解决不发送激活邮件和重置密码邮件的问题 3.在服务器上部署网站 4.加入匿名提问功能 明日任务: 黎柱金 修改数据库用户表,实现用户积分管理功能 晏旭瑞 解决 ...

  9. 20145214《网络攻防》逆向及Bof基础实践

    20145214<网络攻防>逆向及Bof基础实践 实践说明 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何 ...

  10. 经验分享(Android开发)

    以前对于Android开发一点了解都没有,当然,以前觉得是一件很高大上的事情,而且是我没有能力去做的工作,但是在这个小组合作开发Android后,我觉得我有了很大的进步,当然我的进步也是Android ...