Description

小T打算在城市C开设一家外送快餐店。送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方。 快餐店的顾客分布在城市C的N 个建筑中,这N 个建筑通过恰好N 条双向道路连接起来,不存在任何两条道路连接了相同的两个建筑。任意两个建筑之间至少存在一条由双向道路连接而成的路径。小T的快餐店可以开设在任一建筑中,也可以开设在任意一条道路的某个位置上(该位置与道路两端的建筑的距离不一定是整数)。 现给定城市C的地图(道路分布及其长度),请找出最佳的快餐店选址,输出其与最远的顾客之间的距离。

Solution

还比较可做,容易发现树的情况就是直径除以二
基环外向树也类似,其实就是所有可能的最点对的最短路取个 \(max\),也就是 \(max(dis(x,y))\),\(dis(x,y)\) 表示 \(x\)到\(y\) 的最短路,于是就可以做 \(O(n^2)\) 了
实际上如果经过了环了话,那么路径就有两条
我们发现其实这些路径很多都可以归为一类,其实就是断掉环上的某个点后的树中的直径,小于直径的点对就没有必要再考虑了,因为肯定不会算入 \(max(dis(x,y))\) 中

所以问题转化为:我们需要断掉环上的任意一条边,并求出形成的树的直径,并将直径取 \(min\)

这个问题就比较简单了
对于不经过环的可以直接树形DP求出来.

对于经过环的,我们可以任选两个外向树的最长链拼起来,答案就是所有拼法中的最大值
我们给环编个号 \(1,2,3,...cnt\) ,那么路径就只有两种情况,一种是经过点 \(cnt\) 的,一种是不经过的
分开讨论即可,考虑不经过的,设 \(pri[i]\) 表示前 \(i\) 棵外向树构成的最长路,\(f[i]\) 表示第 \(i\) 棵外向树的最长链的长度

\(pri[i]=max(pri[i-1],f[i]+f[v]+dis(u,v))\)
我们可以把 \(dis(u,v)\) 拆成 \(dis[u]-dis[v]\) ,那么就可以维护一个 \(f[v]-dis[v]\) 的最大值优化转移了

复杂度 \(O(n)\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int head[N],nxt[N<<1],to[N<<1],num=1,n,dis[N<<1],pre[N];bool vis[N];
inline void link(int x,int y,int z){nxt[++num]=head[x];to[num]=y;head[x]=num;dis[num]=z;}
bool flag=0;int c[N],cnt=0;ll d[N],f[N],ans=0;
inline void circle(int x,int y){while(x!=y){c[++cnt]=x;d[cnt+1]=d[cnt]+dis[pre[x]];x=to[pre[x]^1];}c[++cnt]=y;
}
inline void dfs(int x,int last){vis[x]=1;for(int i=head[x];i;i=nxt[i]){int u=to[i];if(u==last)continue;if(!vis[u])pre[u]=i,dfs(u,x);else pre[u]=i,circle(x,u),flag=1;if(flag)return ;}vis[x]=0;
}
inline void DFS(int x,int last){for(int i=head[x];i;i=nxt[i]){int u=to[i];if(u==last || vis[u])continue;DFS(u,x);ans=max(ans,f[x]+f[u]+dis[i]);f[x]=max(f[x],f[u]+dis[i]);}
}
ll pri[N],suf[N],p[N],q[N];
int main(){freopen("pp.in","r",stdin);freopen("pp.out","w",stdout);int x,y,z;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d%d",&x,&y,&z);link(x,y,z);link(y,x,z);}dfs(1,1);for(int i=1;i<=n;i++)vis[i]=0;for(int i=1;i<=cnt;i++)vis[c[i]]=1;for(int i=1;i<=cnt;i++)DFS(c[i],c[i]);ll mx=f[c[1]],my=f[c[1]],ret=1e15,res=0,tot=d[cnt]+dis[pre[c[cnt]]];pri[1]=p[1]=f[c[1]];for(int i=2;i<=cnt;i++){pri[i]=max(pri[i-1],mx+f[c[i]]+d[i]);p[i]=max(f[c[i]],-d[i]+my);mx=max(mx,f[c[i]]-d[i]);my=max(my,f[c[i]]+d[i]);}suf[cnt]=q[cnt]=f[c[cnt]];mx=d[cnt]+f[c[cnt]];my=f[c[cnt]]-d[cnt];for(int i=cnt-1;i>=1;i--){suf[i]=max(suf[i+1],mx+f[c[i]]-d[i]);q[i]=max(f[c[i]],d[i]+my);mx=max(mx,f[c[i]]+d[i]);my=max(my,f[c[i]]-d[i]);}ret=max(max(pri[cnt],suf[1]),tot-dis[pre[c[cnt]]]);for(int i=1;i<cnt;i++){res=max(pri[i],suf[i+1]);res=max(res,tot+p[i]+q[i+1]-dis[pre[c[i]]]);ret=min(res,ret);}ans=max(ans,ret);printf("%.1lf\n",ans/2.0);return 0;
}

转载于:https://www.cnblogs.com/Yuzao/p/8519640.html

bzoj 3242: [Noi2013]快餐店相关推荐

  1. NOI2013 快餐店

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

  2. BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec   Memory Limit: 256 MB Submit: 123   Solved: 73 [ Submit][ St ...

  3. [NOI2013]快餐店

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

  4. BZOJ 3244: [Noi2013]树的计数

    传送门 神仙题... 和树的深度有关,由于 $BFS$ 序的性质,显然可以通过把 $BFS$ 序分成若干段来求出深度,每一段就对应某一深度从左到右的所有节点,那么如果确定了分的段数就确定了树的深度(分 ...

  5. BZOJ 3240 [Noi2013] 矩阵游戏 题解

    转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24594825 [原题] 3240: [Noi2013]矩阵游戏 Time Limit ...

  6. NOI2013快餐店【图上找环+线段树】

    NOI 2013 快餐店 NOI 线段树 题目传送点 说白了,就是给个N个点N条边的图,然后求一个点(不一定是给的那N个点),到所有给定的点的路程最大值最小 =≡Σ((( つ•̀ω•́)つ我是蒟蒻,想 ...

  7. BZOJ 3241: [Noi2013]书法家

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3241 题意: 思路:把每个字母分成三部分,两个字母之间还有空的列,所以我一共设了11个状态 ...

  8. [BZOJ3242][Noi2013]快餐店 环套树+线段树

    如果给的是一棵树那么答案显然是直径/2 但是现在给的是一个环套树 那你就枚举一下环上的每条边把它删掉再求直径就好辣(显然你不会走环上的某一条边 这很显然吧- - ) 然后你就要求剩下来的这棵树的直径 ...

  9. 基础省选+NOI-第4部分 动态规划

    1.期望概率DP [整理]简单的数学期望和概率DP [整理]简单的数学期望和概率DP - nimphy - 博客园 期望&概率dp总结 期望&概率dp总结_十分残念的博客-CSDN博客 ...

最新文章

  1. sklearn中随机森林的class_weight的作用?
  2. 微软技术专家为您解读深度学习
  3. 利用python创建学生管理系统软件代码赏析
  4. 合格PHP工程师的知识结构
  5. R_Studio模拟学生成绩对数据简单分析
  6. 【精选】Nginx负载均衡学习笔记(一)实现HTTP负载均衡和TCP负载均衡(官方和OpenResty两种负载配置)...
  7. 理解insert all/insert first的使用
  8. 必不可少需要掌握的嵌入式知识(2) -- 经典数据结构总结之 (链表,队列)
  9. PetShop的系统架构设计
  10. 高等数学第六版下册答案
  11. 运筹学那些事,专科学生学习运筹学之运输问题,No.5
  12. VC++实现镜像劫持(360保险箱启动原理)
  13. 采用WPF开发第二版OFD阅读器
  14. 运筹说 第32期 | 对偶理论与灵敏度分析—灵敏度分析
  15. 想买云服务器,有性能比较好的推荐吗?
  16. 自动化专题讲座:作为自动化工程师,如何才能更好的承担社会责任?
  17. java math 三角函数_Java Math类的常用方法,三角函数运算
  18. 字典写入excel_实例9:用Python自动生成Excel档每日出货清单
  19. 智能优化算法:秃鹰搜索算法 -附代码
  20. java-net-php-python-java门诊信息管理系统计算机毕业设计程序

热门文章

  1. 厚积薄发-Web安全
  2. SwiftUI 开源项目 - ZYSwiftUIFrame 自带服务端的完整示例项目(更新中...)
  3. 【Java 基础】字符串(String、StringBuilder),日期(Date、SimpleDateFormat、Calendar)
  4. 【MyBatis笔记】06-Mapper动态代理
  5. 如何在Linux系统上刷抖音
  6. Linux运维问题解决(2)——Linux设置定时重启系统的方法:定时任务crontab 和 编写脚本
  7. 掌握这个分析方法,数据分析就学会了一半
  8. 帆软报表插件开发之fine-decision中的LogInOutEventProvider扩展
  9. 蓝桥杯java龟兔赛跑_蓝桥杯 1476: [蓝桥杯][基础练习VIP]龟兔赛跑预测
  10. springboot 不使用 thymeleaf_springboot 使用swagger 不显示basic-error-controller解决