题目描述

mhy12345学习了树的直径,于是开始研究图的半径,具体来说,我们需要在图中选定一个地方作为中心,其中这个中心有可能在路径上。

而这个中心的选址需要能够使得所有节点达到这个中心的最短路里面最大值最小(也就是说离中心最远的结点距离尽可能小),求出这个最大值的最小值,作为图的半径。

数据范围

N<=200,W<=100000,M<=19900

数据有梯度

分析与演绎

原题所求:选取一个实点,使得图上所有结点到这个实点的最长距离最短

由于实点既可以取在边上,也可以取在结点上,所以可取范围很大,难以处理。

花费O(m),原题所求转化为在一条边上选取一个实点,使得图上所有结点到这个实点的最长距离最短

预设花费来枚举这条边上的一个实点,原题继续转化图上所有点到一个实点的最长距离最短是多少

这就让我们感到很舒服,设这条边为(x,y)权为z,实点在与x距离为t,这个答案为ans:

ans=max{min(dis[i][x]+t,dis[i][y]+z−t)}

我们可以利用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】图的半径的更多相关文章

  1. 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    题目描述 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取一些原子,排成 ...

  2. 【JZOJ4882】【NOIP2016提高A组集训第12场11.10】多段线性函数

    题目描述 数据范围 解法 三分找出极值,两个二分找出极值的范围. 代码 #include<iostream> #include<stdio.h> #include<str ...

  3. JZOJ 【NOIP2016提高A组集训第16场11.15】兔子

    JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...

  4. 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 ...

  5. 【NOIP2016提高A组集训第14场11.12】随机游走

    题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...

  6. 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP

    好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...

  7. 【JZOJ4890】【NOIP2016提高A组集训第14场11.12】随机游走

    题目描述 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己 ...

  8. 【JZOJ4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列

    题目描述 YJC最近在学习字符串的有关知识.今天,他遇到了这么一个概念:最长公共回文子序列.一个序列S,如果S是回文的且分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...

  9. 【JZOJ4888】【NOIP2016提高A组集训第14场11.12】最近公共祖先

    题目描述 YJC最近在学习树的有关知识.今天,他遇到了这么一个概念:最近公共祖先.对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. ...

随机推荐

  1. IO流19(完) --- RandomAccessFile实现数据的插入 --- 技术搬运工(尚硅谷)

    原hello.txt文件中的内容:abcdefghijklmn 想要实现的效果是,将xyz插入到abc后面,将文件内容变成:abcxyzdefghijklmn @Test public void te ...

  2. 解读Python中 locals() 和 globals() 内置函数

    首先globals() 和 locals() 是作用于作用域下的内置函数,所以我将它们分为作用域类型的内置函数 1.作用域相关: 1)globals() # 返回全局作用域中的所有名字 2)local ...

  3. js 获取复选框 和 并改变状态

    function checkAll() { var checkbox = document.getElementById('vegeids');// var boxes = document.getE ...

  4. 对于ssm过程中的乱码问题的处理

    首先是数据库乱码问题: 1.可以先检测一下是否是数据库的问题: 可以先输入查询语句SHOW VARIABLES LIKE 'character_set_%';,查看所有的编码是否是UTF-8. (一般 ...

  5. Win10操作系统安装—U盘作为启动盘—系统安装到固态硬盘中

    利用U盘作为启动盘安装win10操作系统 1.U盘制作为启动盘,制作工具,我选择的是大白菜(个人觉得还是很好用的) 大白菜http://www.bigbaicai.com/rjjc/syjc/3269 ...

  6. VS2013 IIS Express8.0

    1.下载最新版本的 Microsoft Web Platform Installer 5.0. 2.在组件列表中选择最新版本的 WebMatrix 3.0,安装重启后即可正常使用 IIS Expres ...

  7. fore end common url

    1.Fore end course 1)less http://www.bootcss.com/p/lesscss/2.Fore end official website 1)W3C(HTML/CSS ...

  8. LintCode 链表倒数第n个节点

    找到单链表倒数第n个节点,保证链表中节点的最少数量为n. 样例 给出链表 3->2->1->5->null和n = 2,返回倒数第二个节点的值1. 分析:设两个指针 p1和p2 ...

  9. MyBatis连接Neo4j问题记录:mapper参数传递(节点标签作为参数)

    MyBatis与Neo4j的连接我在上一篇做了,这是链接:https://blog.csdn.net/qq_34233510/article/details/82496101 上一篇中UserMapp ...

  10. CentOS 7 yum 安装与配置MySQL5.7

    1.下载mysql源安装包 wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 2.安装mysql源 yu ...