【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的深度尽可能大. ...
随机推荐
- webServices学习三(概念详解)
WebService通过HTTP协议完成远程调用: (深入分析) WebService只采用HTTP POST方式传输数据,不使用GET方式; -- 握手,WSDL-get, 普通http post的 ...
- react-native连接华为真机
android studio的设置:下载google USB Driver 手机部分1.找到手机开发者模式 设置->系统->关于手机->版本号(多次点击出现开发者模式) 提示你已在开 ...
- Linux程序包管理初步-rpm的使用
在Linux系统上,一般而言,对于程序包管理器来说分为三类: debian:dpt,dpkg; (程序包后缀.deb) rhel:rpm (程序包后缀.rpm) suse:rp ...
- [转]了解screen对象的常用视图属性
前面的话 screen对象基本上只用来表明客户端的能力,其中包括浏览器窗口外部的显示器的信息,如像素高度和宽度等.每个浏览器中的screen对象都包含着各不相同的属性.本文将详细介绍screen对象的 ...
- MacBook安装QF9700网卡驱动
HOW TO USE A GENERIC USB ETHERNET ADAPTER QF9700 ON MAC OS X 20 February 2016 macOS Zahid Mahmood ...
- java并发系列(三)-----ReentrantLock(重入锁)功能详解和应用演示
1. ReentrantLock简介 jdk中独占锁的实现除了使用关键字synchronized外,还可以使用ReentrantLock.虽然在性能上ReentrantLock和synchronize ...
- char类型和int类型之间的转换
在视屏课程第二章里,我们已经学习了一些常用的数据类型转换.然而,有一些时候我们会经常会遇到将char类型转换成int类型,或者需要将int类型转换为char类型的情况. 这里,我们来探讨一下这种不常用 ...
- 关于python 环境变量
1.默认命令行的启动的python 版本,这依赖于系统的环境变量. 见上一篇关于linux 环境变量的PATH 变量的设置 2.python 中 import 包的搜索路径, 即除了当前程序目录,能i ...
- js 百度地图和谷歌地图的选择
最近手上接到一个需求: 国外的域名访问,显示谷歌地图 国内的域名访问,显示百度地图 切换中英文的时候,中文->显示百度地图,英文->能显示谷歌地图就显示谷歌地图,不能显示(报错)就显示百度 ...
- Ubuntu 16.04 LTS安装Docker最新版
一.安装Docker的先决条件 1.运行64位CPU构架的计算机(目前只能是x86_64和amd64),请注意,Docker目前不支持32位CPU.2.运行Linux 3.8或更高版本内核.一些老版本 ...