【JZOJ4884】【NOIP2016提高A组集训第12场11.10】图的半径
题目描述
mhy12345学习了树的直径,于是开始研究图的半径,具体来说,我们需要在图中选定一个地方作为中心,其中这个中心有可能在路径上。
而这个中心的选址需要能够使得所有节点达到这个中心的最短路里面最大值最小(也就是说离中心最远的结点距离尽可能小),求出这个最大值的最小值,作为图的半径。
数据范围
N<=200,W<=100000,M<=19900
数据有梯度
分析与演绎
原题所求:选取一个实点,使得图上所有结点到这个实点的最长距离最短。
由于实点既可以取在边上,也可以取在结点上,所以可取范围很大,难以处理。
花费O(m),原题所求转化为在一条边上选取一个实点,使得图上所有结点到这个实点的最长距离最短。
预设花费来枚举这条边上的一个实点,原题继续转化图上所有点到一个实点的最长距离最短是多少。
这就让我们感到很舒服,设这条边为(x,y)权为z,实点在与x距离为t,这个答案为ans:
我们可以利用O(n)的时间来求得答案,但总的复杂度很高。
目前演绎的代价还是很大的,考虑继续分析。
考虑对时间复杂度影响最大的步骤,就是枚举一条边上实点的步骤。
这个复杂度为O(+∞)。
考虑交集优化:
随着t从x到y的动态过程, 显然有很多实点冗余的。
对于这样的动态过程,可以考虑刻画图像来反映变化过程。
由于dis[i][x]+t是增函数,dis[i][y]+z−t是减函数,并且它们都是斜率为1或-1的一次函数。
它们要取最小值,所以它们合起来就是一个锯齿形。如下图。
n个锯齿形图像堆叠到一起。
使它们取较大值,最终图像为:
然后,我们要取这个图像上最低一点。
显然最低点都存在于两峰之间。
一个t值为峰当且仅当满足dis[i][x]+t=dis[i][y]+z−t。
这个一次方程易求解,所以n个峰值及其横坐标我们可以花O(n)代价得知。
既然最低点只存在于两峰之间,那么我们将每个峰值横坐标排序。
取两峰的编号v,v+1,这个转折点即是满足dis[v][y]+t=dis[v+1][x]+z−t的t值。
给所有转折点(即最低点)取最小值即为这条边的答案。
总的时间复杂度为O(mnlogn)。
代码
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="center.in";
const char* fout="center.out";
const int inf=0x7fffffff;
const int maxn=207,maxm=40007;
int n,m,i,j,k,l;
int f[maxn][maxn],a[maxm][3];
double ans=0,ans1,c1,c2,x;
struct node{
int x,y;
}c[maxn];
bool cmp(node a,node b){
return a.x>b.x || a.x==b.x && a.y<b.y;
}
void floyd(){
int i,j,k;
for (k=1;k<=n;k++)
for (i=1;i<=n;i++)
for (j=1;j<=n;j++){
if (f[i][k]>2000000000 || f[k][j]>2000000000) continue;
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d%d",&n,&m);
memset(f,127,sizeof(f));
for (i=1;i<=n;i++) f[i][i]=0;
for (i=1;i<=m;i++){
scanf("%d%d%d",&j,&k,&l);
a[i][0]=j;
a[i][1]=k;
a[i][2]=l;
f[j][k]=min(f[j][k],l);
f[k][j]=min(f[k][j],l);
}
floyd();
ans=inf;
for (i=1;i<=m;i++){
ans1=0;
for (j=1;j<=n;j++) c[j].x=f[j][a[i][0]],c[j].y=f[j][a[i][1]];
sort(c+1,c+n+1,cmp);
c1=0;
for (j=1;j<n;j++){
c2=c[j+1].x;
c1=max(c1,(double)c[j].y);
if (c1<c2 && c1+a[i][2]<c2 || c1>c2 && c2+a[i][2]<c1) continue;
ans=min(ans,(c1+a[i][2]+c2)*0.5);
}
}
printf("%.2lf",ans);
return 0;
}
启发
考虑某个值得动态变化过程,可以刻画图像。
【JZOJ4884】【NOIP2016提高A组集训第12场11.10】图的半径的更多相关文章
- 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰
题目描述 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取一些原子,排成 ...
- 【JZOJ4882】【NOIP2016提高A组集训第12场11.10】多段线性函数
题目描述 数据范围 解法 三分找出极值,两个二分找出极值的范围. 代码 #include<iostream> #include<stdio.h> #include<str ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】兔子
JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...
- 【NOIP2016提高A组集训第14场11.12】随机游走
题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...
- 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP
好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...
- 【JZOJ4890】【NOIP2016提高A组集训第14场11.12】随机游走
题目描述 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己 ...
- 【JZOJ4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列
题目描述 YJC最近在学习字符串的有关知识.今天,他遇到了这么一个概念:最长公共回文子序列.一个序列S,如果S是回文的且分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...
- 【JZOJ4888】【NOIP2016提高A组集训第14场11.12】最近公共祖先
题目描述 YJC最近在学习树的有关知识.今天,他遇到了这么一个概念:最近公共祖先.对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. ...
随机推荐
- OPENCV 图像缩放
工程下载地址 https://download.csdn.net/download/qq_16596909/11522434 opencv4 java netbeans开发,基于maven 可以按照倍 ...
- leetcode 699. Falling Squares 线段树的实现
线段树实现.很多细节值得品味 都在注释里面了 class SegTree: def __init__(self,N,query_fn,update_fn): self.tree=[0]*(2*N+2) ...
- 2019.10.25 csp-s模拟测试87 反思总结
一次非常神奇的考试,考完试以后看着T2的0pts突然笑死我自己 太智障了这什么神奇的题意理解错误23333 T1一眼分类讨论,两眼二分,觉得分类讨论有点玄学但是出题人八成不会卡[何],然后本着对二分的 ...
- hadoop2.2 window下报错的问题(winutils.exe)
在windows下开发hadoop一直正常,但把hadoop集群升级到2.0版本以上,在eclipse下执行程序会报打不到winutils.exe的错误,这是因为hadoop2.2没有发布winuti ...
- Linux时间设置命令
1.date: 语法格式:date [-u] [-d datestr] [-s datestr] [--utc] [--universal] [--date=datestr] [--set=dates ...
- Docker(一)简介及核心概念
1.简介 Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这 ...
- html5绘图工具选择
1. Chart.js 基于html5, 完全开源免费 功能过于简单,只有6种图,能满足小系统需求,使用简便,效果比较炫. http://www.bootcss.com/p/chart.js/ 2. ...
- 20190818 [ B ]-½
请看到这个蒟蒻博客的人注意一下. 这是简单的[ B ]场考试,如果需要[ A ]场题解请去神犇们的blog. [ B ]场不需要题解,恩? 太蒟蒻了QAQ 考试过程: 怀着我是蒟蒻我怕谁的心情. 首先 ...
- vim 的列操作
删除列1.光标定位到要操作的地方.2.CTRL+v 进入“可视 块”模式,选取这一列操作多少行.3.d 删除. 插入列插入操作的话知识稍有区别.例如我们在每一行前都插入"() ": ...
- 锋利的jQuery学习笔记之jQuery选择器
在介绍jQuery选择器之前,先简单介绍一下CSS选择器---> 一.CSS选择器 常见的CSS选择器有以下几种: 选择器 语法 描述 示例 标签选择器 E{CSS规则} 以文档元素为选择符 t ...