BZOJ3242/UOJ126 [Noi2013]快餐店
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
Description
小T打算在城市C开设一家外送快餐店。送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方。 快餐店的顾客分布在城市C的N 个建筑中,这N 个建筑通过恰好N 条双向道路连接起来,不存在任何两条道路连接了相同的两个建筑。任意两个建筑之间至少存在一条由双向道路连接而成的路径。小T的快餐店可以开设在任一建筑中,也可以开设在任意一条道路的某个位置上(该位置与道路两端的建筑的距离不一定是整数)。 现给定城市C的地图(道路分布及其长度),请找出最佳的快餐店选址,输出其与最远的顾客之间的距离。
Input
第一行包含一个整数N,表示城市C中的建筑和道路数目。
接下来N行,每行3个整数,Ai,Bi,Li(1≤i≤N;Li>0),表示一条道路连接了建筑Ai与Bi,其长度为Li 。
Output
仅包含一个实数,四舍五入保留恰好一位小数,表示最佳快餐店选址距离最远用户的距离。
注意:你的结果必须恰好有一位小数,小数位数不正确不得分。
Sample Input
1 4 2
1 3 2
2 4 1
Sample Output
HINT

数据范围
对于 10%的数据,N<=80,Li=1;
对于 30%的数据,N<=600,Li<=100;
对于 60% 的数据,N<=2000,Li<=10^9;
对于 100% 的数据,N<=10^5,Li<=10^9
正解:树形$DP+dfs$
解题报告:
首先我们要明确,直接求图的直径是错误的。
反例可以想想,大概就是在环上等距的三个点,然后其中一个点往外拓展了一棵树,由于我求出来之后按理要放在直径的中点上,但这种情况显然不满足。
下面我们需要考虑如何求一个点,使得它到图中的所有点的最大距离最小。
对于这种带了环的题目(又是基环外向树),我们一般是断掉环上的某一条边,再作考虑。
考虑断掉环上一条边,然后求树的直径的正确性,显然一条合法的路径肯定不能经过一整个环,那么就有一些部分是肯定不会经过的,我就可以枚举这些肯定不会经过的一条边,断掉,对于树与树之间肯定无影响,对环上的点,由于有两条路径,删掉不会导致“错过”最优答案。
断掉一条边之后变成一棵树,对于树而言求直径肯定就是对的了。
如果能快速地查询断掉这条边之后对得到的树的直径的查询就能得到答案。
我们先$dfs$一遍得到环上每个点拓展出去的树的直径,最终答案不会小于等于最大直径$/2$。
我们先人工地断开$1$到$cnt$(假设环长为$cnt$)的边,从前往后求一遍$u$,$v$:$u$表示的是$max(前缀中最大的一条链+当前节点的树的最大深度)$,$v$表示的是$max(前缀中两棵树的最大深度+这两个根节点直接的距离)$,后缀也做一遍,记为$u2,v2$。
那么我最后枚举断掉哪条边时,就可以快速合并了!
我们枚举断掉$i$到$i+1$这条边时,答案应该是$max(max(v[i],v2[i+1]),u[i]+u2[i+1]+1$到$cnt$的边权)。
公式的含义就是,前缀的一段的最大直径,后缀的一段的最大直径,加上,前缀和后缀的$u$经过$1$到$cnt$这条边之后组合起来的直径,三个取一个$max$即为答案。
我们显然需要使得这个最短。
最后我们需要和最大的树的直径取一个$max$,原因上面已经说了...
ps:话说这道题似乎线段树也可以做,不过复杂不少,而且细节很多,还多了一个$log$...
//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
using namespace std;
typedef long long LL;
const int MAXN = 100011;
const int MAXM = 200011;
int n,ecnt,first[MAXN],to[MAXM],next[MAXM],w[MAXM];
int b[MAXN],scnt,father[MAXN],val[MAXN],fa_w[MAXN];//val[i]表示环上第i个点到第i+1个点的距离
bool iscircle[MAXN],vis[MAXN];
LL f[MAXN],pre[MAXN],best[MAXN],pre2[MAXN],best2[MAXN],ans,chain; inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && 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;
} inline void dfs_find(int x,int fa){
vis[x]=1;
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(v==fa) continue;
if(vis[v]) {
if(iscircle[v]) continue;
int u=x;
while(u!=v) {
iscircle[u]=true;
b[++scnt]=u; val[scnt]=fa_w[u];
u=father[u];
}
iscircle[u]=true;
b[++scnt]=v; val[scnt]=w[i];
continue;
}
father[v]=x; fa_w[v]=w[i]; vis[v]=true;
dfs_find(v,x);
}
} inline void dfs(int x,int fa){
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(v==fa || iscircle[v]) continue;
dfs(v,x);
chain=max(chain,f[x]+f[v]+w[i]);
f[x]=max(f[x],f[v]+w[i]);
}
} inline void work(){
n=getint(); int x,y,z;
for(int i=1;i<=n;i++) {
x=getint(); y=getint(); z=getint();
next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z;
next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x; w[ecnt]=z;
}
dfs_find(1,0); LL tot=0,da=0; int now;
for(int i=1;i<=scnt;i++) dfs(b[i],0);
for(int i=1;i<=scnt;i++) {
tot+=val[i-1];//环上权值前缀和
now=b[i];
pre[i]=max(pre[i-1],tot+f[now]);
best[i]=max(best[i-1],tot+da+f[now]);
da=max(da,f[now]-tot);//方便后面组合得到完整答案
}
tot=0; LL duan=val[scnt]; val[scnt]=da=0;
for(int i=scnt;i>=1;i--) {
tot+=val[i];
now=b[i];
pre2[i]=max(pre2[i+1],tot+f[now]);
best2[i]=max(best2[i+1],tot+da+f[now]);
da=max(da,f[now]-tot);
} ans=best[scnt]; LL choose;
for(int i=1;i<scnt;i++) {
choose=max(best[i],best2[i+1]);
choose=max(choose,pre[i]+pre2[i+1]+duan);
if(choose<ans) ans=choose;
}
ans=max(ans,chain);
if(ans&1) printf("%lld.5",ans>>1);
else printf("%lld.0",ans>>1);
} int main()
{
work();
return 0;
}
BZOJ3242/UOJ126 [Noi2013]快餐店的更多相关文章
- CF835F Roads in the Kingdom/UOJ126 NOI2013 快餐店 树的直径
传送门--CF 传送门--UOJ 题目要求基环树删掉环上的一条边得到的树的直径的最小值. 如果直接考虑删哪条边最优似乎不太可做,于是考虑另一种想法:枚举删掉的边并快速地求出当前的直径. 对于环上的点, ...
- 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 希望快餐店的地址选在离最 ...
- bzoj3242 [Noi2013]快餐店
Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...
- 【uoj126】 NOI2013—快餐店
http://uoj.ac/problem/126 (题目链接) 题意 求基环树直径. Solution zz选手迟早退役,唉,右转题解→_→:LCF 细节 拓扑排序的时候度数为0时入队.我在想什么w ...
- BZOJ3242 [Noi2013]快餐店 【环套树 + 单调队列dp】
题目链接 BZOJ3242 题解 题意很清楚,找一点使得最远点最近 如果是一棵树,就是直径中点 现在套上了一个环,我们把环单独拿出来 先求出环上每个点外向树直径更新答案,并同时求出环上每个点外向的最远 ...
- 3242: [Noi2013]快餐店 - BZOJ
Description 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. 快餐店的顾客分布在城 ...
- 动态规划:NOI2013 快餐店
Description 小 T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近 的地方. 快餐店的顾客分布 ...
- NOI2013 快餐店
http://uoj.ac/problem/126 总的来说,还是很容易想的,就是有点恶心. 首先,很明显只有一个环. 我们先找出这个环,给各棵树编号id[i],然后各棵树分别以环上的点为根,求出每个 ...
随机推荐
- php5.4新特性实践
本机安装的是wampserver2.2e-php5.4.3-httpd2.2.22-mysql5.5.24-32b.exe集成包 自带了php5.4 1. 数组写法 定义一个数组 过去: $arr = ...
- Introduction to Mathematical Thinking - Week 2
基本数学概念 real number(实数):是有理数和无理数的总称 有理数:可以表达为两个整数比的数(a/b, b!=0) 无理数是指除有理数以外的实数 imply -- 推导出 不需要 A 能推导 ...
- ASP-Command-SQL格式
conn.open constrSet c=Server.CreateObject("ADODB.Command")With cSet .ActiveConnection = co ...
- Integrate-And-Fire Models(转)
Integrate-And-Fire Models 基础知识 轴突:动作电位(电位差形成电流)=神经递质发放=脉冲产生树突或细胞体:神经递质的接受=产生内外膜电位差(电流产生)=接收脉冲脉冲编码:多采 ...
- Mybatis参数总结(转载)
转载自: MyBatis传入多个参数的问题 mybatis传递参数总结 一.单个参数 1.基本数据类型 (1)直接使用 List<ChargeRuleDO> tests(long id); ...
- 软件磁盘阵列(RAID)
RAID软件磁盘阵列 RAID 即廉价磁盘冗余阵列,其高可用性和可靠性适用于大规模环境中,相比正常使用,数据更需要被保护.RAID 是将多个磁盘整合的大磁盘,不仅具有存储功能,同时还有数据保护功能. ...
- R&python机器学习之朴素贝叶斯分类
朴素贝叶斯算法描述应用贝叶斯定理进行分类的一个简单应用.这里之所以称之为“朴素”,是因为它假设各个特征属性是无关的,而现实情况往往不是如此. 贝叶斯定理也称贝叶斯推理,早在18世纪,英国学者贝叶斯(1 ...
- Python Variable Scope
Python中的变量的作用域有时会让像我这样的初学者很头疼. 其实只需要掌握以下两点: 1. Python能够改变变量作用域的代码段是def.class.lamda; 而if/elif/else ...
- request doesn't contain a multipart/form-data or multipart/mixed stream ……
有文件控件"file"的表单,在提交的时候,直接使用了ajax提交,结果报了一堆错,原来这个东东要提交表单,还要用post方式,最后更改为: $("#saveForm&q ...
- java中byte数组与int,long,short间的转换
http://blog.csdn.net/leetcworks/article/details/7390731 package com.util; /** * * <ul> * <l ...