[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 条南北向街道所形 ...
随机推荐
- C++ GUI Qt4编程-创建自定义窗口部件
C++ GUI Qt4编程-创建自定义窗口部件 Qtqt4 通过Qt窗口部件进行子类化或者直接对QWidget进行子类化,就可以创建自定义窗口部件,下面示范两种方式,并且也会说明如何把自定义窗口部 ...
- 【leetcode】1144. Decrease Elements To Make Array Zigzag
题目如下: Given an array nums of integers, a move consists of choosing any element and decreasing it by ...
- 文件打包压缩——tar
tar——压缩数据/解压数据内容 命令语法: tar zcvf 生成压缩包路径/压缩包.tar.gz 压缩数据01,02,03.... 巧记: 压缩名称为tar.gz,可以理解为tar命令,g ...
- cookie、session和会话保持
1.会话 在程序中,会话跟踪是很重要的事情.理论上,一个已登录用户,在这次登录后进行的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆.例如,用户 A 在 ...
- EQS 自定义Context 如何用Testing Pawn 进行测试?
比如自定义了一个玩家的Context, 那么需要把这个玩家直接放置到场景中 在Context中override Provide Single Actor函数,按类型获取所有的Actor,其中第一个作为 ...
- [CSP-S模拟测试]:梦境(贪心+小根堆)
题目描述 智者奥尔曼曾说过:有缘的人即使相隔海角天涯,也会在梦境中相遇. $IcePrince\text{_}1968$和$IcePrincess\text{_}1968$便是如此.有一天$IcePr ...
- open 函数处理文件
open函数用于文件处理 操作文件时,一般需要经历如下步骤:1 打开文件 2 操作文件 f = open("文件名" , ' 打开文件方式' ) 文件句柄 ...
- np.asarray(a, dtype=None, order=None)
np.asarray(a, dtype=None, order=None) 参数a:可以是,列表, 列表的元组, 元组, 元组的元组, 元组的列表,多维数组 参数dtype=None, order=N ...
- 顶级域名、一级域名、二级域名与IP
转自:https://blog.csdn.net/qq_38071429/article/details/80339091 域名:可分三级,一级域名,二级域名,三级域名.是由一串字符+域名后缀组成,我 ...
- 线性代数之——SVD 分解
SVD 分解是线性代数的一大亮点. 1. SVD 分解 \(A\) 是任意的 \(m×n\) 矩阵,它的秩为 \(r\),我们要对其进行对角化,但不是通过 \(S^{-1}A S\).\(S\) 中的 ...