【题解】[CJOI2019Chebnear]

题目描述

给定平面上有\(n\)个仇人,\((x,y) ,x,y \in R^+\) ,\(n\)个人都是仇人关系,而有仇人关系的一对人的切比雪夫距离若\(\le k\)则会发生“吵架”。可是,对于有些仇人\(i\)和\(j\),先记为三元组\(P(t,i,w)\),他们的的仇人关系并不深,假设给全体\(n\)个人每人\(\ge w\)的钱他们就变为朋友了。而朋友不会吵架,而且朋友的朋友也是你的朋友。

现在问你,你最少给多少钱\(w\)可是让所有人不吵架?

数据范围

\(n\le100000,m\le100000\)

说明

切比雪夫距离:\(d=max(|x_i-x_j|,|y_i-y_j|)\)

\(Solution\)

显然二分答案\(w\)。接下来的任务就是当给每个人\(w\)钱的时候,是否有人吵架了。

然后\(O(m)\)枚举那些朋友可以连接,直接用并查集维护朋友关系。

考虑暴力。

  • \(O(n^2)\)枚举每个点对,看他们是否吵架。这样显然超时。

我们仔细思考一下,发现吵架只和以下两个因素有关。

  • \(y\)安全但\(x\)距离过近。
  • \(x\)安全但\(y\)距离过近。
  • 朋友

朋友关系已经用并查集维护了,可以\(O(\alpha(n))=O(1)\)查询。接下来就是\(x,y\)的问题了。

考虑把所有点按\(x\)排序。这样我们就可以快速确定一段区间内的人是否有可能\(x\)过近,然后对于这些点\(O(n_?^2)\)枚举是否会吵架就好了。

但是怎么缩小\(n_?\)呢?

对于平面最近点对问题,可以证明\(n_? \le 6\)。这里我们也可以类比,每次和最近点对一样,直接从中间分开,分治。我们的\(n_?\)一定比最近点对的\(n_?\)还要小,因为我们还有\(k\)的限制呀,帮助我们剪枝。

接下来上代码了,今天的代码是不是码风很棒?

#include<bits/stdc++.h>

#define RP(t,a,b) for(register int (t)=(a),edd_=(b);t<=edd_;++t)
#define DRP(t,a,b) for(register int (t)=(a),edd_=(b);t>=edd_;--t)
#define ERP(t,a) for(int t=head[a];t;t=e[t].nx)
#define pushup(x) seg[(x)]=seg[(x)<<1]+seg[(x)<<1|1]
#define midd register int mid=(l+r)>>1
#define TMP template<class ccf>
#define rgt L,R,mid,r,pos<<1|1
#define lef L,R,l,mid,pos<<1
#define all 1,n,1 using namespace std;typedef long long ll;
TMP inline ccf Max(ccf a,ccf b){return a<b?b:a;}
TMP inline ccf Min(ccf a,ccf b){return a<b?a:b;}
TMP inline ccf Abs(ccf a){return a<0?-a:a;}
TMP inline ccf qr(ccf k){
char c=getchar();ccf x=0;int q=1;
while(c<48||c>57)q=c==45?-1:q,c=getchar();
while(c>=48&&c<=57)x=x*10+c-48,c=getchar();
return q==-1?-x:x;}
//-----------------template&IO------------------
int n,m;double k;
const int maxn=1e5+5;
struct node{
double x,y;int id;
inline bool operator <(node a){return x<a.x;}
inline double operator -(node a){return Max(Abs(x-a.x),Abs(y-a.y));}
}data[maxn];
struct E{
int fr,to;double w;
inline bool operator <(E a){return w<a.w;}
}e[maxn<<1];
int rr[maxn];
inline int q(int x){register int t=x,temp,i=x;
while(rr[t]!=t) t=rr[t];
while(rr[i]!=i) temp=rr[i],rr[i]=t,i=temp;
return t;
}
inline void j(int x,int y){rr[q(x)]=q(y);}
inline bool in(int x,int y){return q(x)==q(y);}
struct DFN{
double pos;int id;
inline bool operator <(DFN x){return pos<x.pos;}
}dfn[maxn]; bool divd(int lb,int rb){register int mid=(lb+rb)>>1;
if(lb>=rb) return 1;
if(!divd(lb,mid)) return 0;
if(!divd(mid+1,rb)) return 0;
register int L=mid,R=mid;
while(data[mid].x-data[L-1].x<=k&&L>lb) --L;
while(data[R+1].x-data[mid].x<=k&&R<rb) ++R;
RP(t,L,R)RP(i,t+1,R)
if(!in(data[t].id,data[i].id)&&data[t]-data[i]<=k)
return 0;
return 1;
} inline bool chek(double x){
RP(t,1,n) rr[t]=t;
RP(t,1,m) if(x>=e[t].w) j(e[t].fr,e[t].to);
return divd(1,n);
} int main(){
#ifndef ONLINE_JUDGE
freopen("chebnear.in","r",stdin);
freopen("chebnear.out","w",stdout);
#endif
cin>>n>>m>>k;
RP(t,1,n)
cin>>data[t].x>>data[t].y,data[t].id=t;
RP(t,1,m)
cin>>e[t].fr>>e[t].to>>e[t].w;
sort(data+1,data+n+1);
sort(e+1,e+m+1);
int l=1,r=m,ans=m;
do{
midd;
if(chek(e[mid].w))
r=mid-1,ans=Min(ans,mid);
else
l=mid+1;
}while(l<=r);
if(chek(0)) ans=0;
printf("%.3lf\n",e[ans].w);
return 0;
}

【题解】[CJOI2019Chebnear]的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. [转] makeFile文件作用

    源文件地址 makefile关系到了整个工程的编译规则.一个工程中的源文件不计数,其按类型.功能.模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后 ...

  2. concurrencyProgrammingGuide 1

    thread用来表述执行代码的独立path.os x的线程执行基于POSIX 线程API. process用来表述一个运行操作,可以包含多个线程. task用来描述工作的抽象概念. Concurren ...

  3. RxJava Android(RxAndroid) 开发全家桶

    RxJava 在 Android 应用开发中越来越流行,但是由于其门槛稍高,初次使用不免遇到很多问题,例如在 RxJava 常见的错误用法 和 不该使用 RxJava 的一些情况 中所描述的情况.为了 ...

  4. VS2010中打开VS2012项目的方法

    VS2012中对C#的支持度非常好,不管是编写方便程度(不需要插件就能高亮代码及代码自动提示功能),还对MFC的一些功能优化很多. 修改两个工程文件就把VS2012的项目移植到VS2010中去的方法如 ...

  5. python数据分析入门学习笔记儿

    学习利用python进行数据分析的笔记儿&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据 ...

  6. nx sdk

    最近在做ns 任天堂略坑.. 他想做成一键安装,可总是有些问题,这样再去找就很麻烦了.都是包在里面的,要看很多文档 第一个问题是 NintendoSDK Configuration Manager 这 ...

  7. 计算机图形学OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理,用法 .(转)

    单位矩阵 对角线上都是1,其余元素皆为0的矩阵. 在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,我们称这种矩阵为单位矩阵. 它是个方阵,除左上角到右下角的对角线(称为主对角线)上的元素 ...

  8. 2016.8.19 在dialog上增加一个button出现错误:failed to execute setAttribute on Element...

    目标:想要在dialog上多加一个button. 语法来自: http://api.jqueryui.com/dialog/#option-buttons   可见新增在dialog上的button要 ...

  9. UNP学习笔记(第四章 基本TCP套接字编程)

    本章讲解编写一个完整的TCP客户/服务器程序所需要的基本套接字函数. socket函数 #include <sys/socket.h> int socket(int family,int ...

  10. swiper-demo1

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...