[51Nod2558] 选址
考虑二分答案 $F$ ,那么现在的问题变成是否对于覆盖并有交集。
考虑边 $(u,v)$ ,若覆盖并在 $(u,v,w)$ 线段中,设点 $i$ 走到 $u$ 号后还能走 $F1$ , 走到 $v$ 还能走 $F2$ ,则现在要求的是一个子问题:求在 $n$ 个 $(0,F1),(w-F2+1,w)$ 中判断是否有交集,若存在点 $x$ 使得 $n$ 个线段都能被覆盖时,$x$ 肯定为 $F1$ 或 $w-F2+1$ ,所以直接暴力枚举即可,时间复杂度 $O(n^4\log 值域)$。
而如何优化时间复杂度,考虑如何快速计算贡献,直接离散化后差分计算即可。
时间复杂度 $O(n^3\log 值域)$。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
using namespace std;
inline int read(){
int f=,ans=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){ans=ans*+c-'';c=getchar();}
return f*ans;
}
const int MAXN=;
struct Edge{
int u,v,w;
}x[MAXN*MAXN];
int n,m,dis[MAXN][MAXN];
double f1[MAXN][MAXN*MAXN],f2[MAXN][MAXN*MAXN],l,r,minn=LLONG_MAX,eps=1e-,num[MAXN<<],tmp[MAXN<<];
int M;
int G1[MAXN<<][MAXN<<],G2[MAXN<<][MAXN<<];
int NU[MAXN<<],cnt[MAXN],Cnt;
inline int Q(double res){return lower_bound(tmp+,tmp+M+,res)-tmp;}
inline bool Query(int id,double G){
memset(NU,,sizeof(NU));memset(cnt,,sizeof(cnt));
int Num=;
num[++Num]=;tmp[Num]=num[Num];
num[++Num]=x[id].w;tmp[Num]=num[Num];
for(register int i=;i<=n;i++){
double t1=f1[i][id],t2=x[id].w-f2[i][id];
Cnt++;
if(t1>=) num[++Num]=min(t1,(double)x[id].w),tmp[Num]=num[Num];
if(f2[i][id]>=) num[++Num]=max((double),t2),tmp[Num]=num[Num];
}
sort(tmp+,tmp+Num+);
M=unique(tmp+,tmp+Num+)-tmp-;
for(register int i=;i<=Num;i++) Cnt++,num[i]=lower_bound(tmp+,tmp+M+,num[i])-tmp;
for(register int i=;i<=n;i++){
Cnt++;
double t1=f1[i][id],t2=x[id].w-f2[i][id];
if(t1>=){
int l=,r=Q(min(t1,(double)x[id].w))+;
G1[l][++NU[l]]=i;G2[l][NU[l]]=;
G1[r][++NU[r]]=i;G2[r][NU[r]]=-;
}
if(f2[i][id]>=){
int l=Q(max((double),t2));
G1[l][++NU[l]]=i;G2[l][NU[l]]=;
}
}
int Sum=;
for(register int i=;i<=M;i++){
for(register int j=;j<=NU[i];j++){
Cnt++;
int f=G1[i][j],opt=G2[i][j];
if(opt==){
if(cnt[f]==) Sum++;
cnt[f]++;
}else{
if(cnt[f]==) Sum--;
cnt[f]--;
}
}if(Sum==n) return ;
}return ;
}
inline bool check(double G){
for(register int u=;u<=n;u++){
for(register int i=;i<=m;i++){
f1[u][i]=G-dis[u][x[i].u];
f2[u][i]=G-dis[u][x[i].v];
}
}
for(register int i=;i<=m;i++)
if(Query(i,G)) return ;
return ;
}
int main(){
// freopen("make.in","r",stdin);
n=read(),m=read();
memset(dis,/,sizeof(dis));
for(int i=;i<=m;i++){
int u=read(),v=read(),w=read();
r+=w;
x[i].u=u,x[i].v=v,x[i].w=w;
dis[u][v]=dis[v][u]=w;
}
for(int i=;i<=n;i++) dis[i][i]=;
for(int p=;p<=n;p++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][p]+dis[p][j]);
while(l<=r){
double mid=(l+r)/2.0;
if(check(mid)) minn=min(minn,mid),r=mid-eps;
else l=mid+eps;
}printf("%.9lf\n",minn);
}
[51Nod2558] 选址的更多相关文章
- [NOIP2014] 提高组 洛谷P2038 无线网络发射器选址
题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...
- 基于K2 BPM的大型连锁企业开关店选址管理解决方案
业内有句名言:“门店最重要的是什么?第一是选址,第二是选址,第三还是选址” 选址是一个很复杂的综合性商业决策过程,需要定性考虑和定向分析.K2开关店&选址管理方案重点关注:如何开出更好的店?在 ...
- NOIP2014 无线网络发射器选址
1.无线网络发射器选址 (wireless.cpp/c/pas) [问题描述] 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平 ...
- Codevs 1507 酒厂选址
1507 酒厂选址 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description Abstinence(戒酒)岛的居民们酷爱一种无酒精啤酒 ...
- BZOJ 1835: [ZJOI2010]base 基站选址 [序列DP 线段树]
1835: [ZJOI2010]base 基站选址 题目描述 有N个村庄坐落在一条直线上,第i(i>1)个村庄距离第1个村庄的距离为Di.需要在这些村庄中建立不超过K个通讯基站,在第i个村庄建立 ...
- 动态规划(斜率优化):[CEOI2004]锯木厂选址
锯木场选址(CEOI2004) 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能按照一个方向运输:朝山下运.山脚下有 ...
- Floyd算法应用-医院选址问题
1)问题描述 n个村庄之间的交通图可以用有向网图来表示,图中边<vi, vj>上的权值表示从村庄i到村庄j的道路长度.现在要从这n个村庄中选择一个村庄新建一所医院,问这所医院应建在哪个村庄 ...
- NOIP2014_day2:无线网络发射器选址
#include<stdio.h>//NOIP2014 day2 :无线网络发射器选址 ,max=; ][]; void wifi(int a,int b,int c) { int i,j ...
- 关于NOIP2014“无线网络发射器选址”一题的衍生题目的思考及思维方向
无线网络发射器选址 题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形 ...
随机推荐
- java:集合输出之foreach输出三
java:集合输出之foreach输出三 foreach输出: List<String> allList = new ArrayList<String>(); allList. ...
- 一个错误导致懂了mac系统的PATH环境变量
一个完全不懂mac系统的强迫症小白,由于搭建环境都按照百度走,所以在执行命令echo $PATH查看PATH内容时发现怎么有这样一串东西 /usr/local/bin:/usr/bin:/bin:/u ...
- java 生成透明背景图片
//开始绘图 graphics2d.setBackground(Color.WHITE); graphics2d.clearRect(0, 0, width, height); graphics2d. ...
- python+selenium模拟京东登录后台
python+selenium模拟京东登录后台 import json from time import sleep from selenium import webdriver #from sele ...
- iOS Core Image-----十行代码实现微信朋友圈模糊效果
昨天下午微信的朋友圈着实火了一把,在这之后好多程序员都通过抓包工具看到了原图,但是我却在想,网上说是在移动前端做到的那是怎么做到的呢,经过一些学习,终于掌握了一些Core Image的知识,做出了相应 ...
- qs的两个用途
qs是npm安装的库 1.qs.stringify() 将对象序列化成URL的形式,以&进行拼接 const Qs = require('qs'); let obj= { method: ...
- adaboost面试题
1.简述权值更新方法 (1)初始化权值分布: (2)找到误差最小的弱分类器: (3)计算弱分类器的权值: (4)更新下一轮样本的权值分布: (5)集合多个弱分类器成一个最终的强分类器. 2.为什么能快 ...
- 贪心整理&一本通1431:钓鱼题解
题目传送 (其实有一个更正经的题解) 看了许久,发现这题貌似就是一个动态规划啊,但毕竟是贪心题库里的题,还是想想用贪心解吧. 经过(借鉴大佬思路)十分复杂的思考后,终于理解出了这题的贪心思路.该题的难 ...
- [CSP-S模拟测试]:小P的单调数列(树状数组+DP)
题目描述 小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质.经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和.并且以这个为基础,小$P$还可以求 ...
- bootstrap动态调用select下拉框
html代码: <label for="classify" class="col-sm-2 control-label">填报部门:</lab ...