题目描述:

bz

luogu

题解:

把坐标系看反了持续$WA$系列。

对偶图+并查集维护。

先处理出树对树、树对墙的空隙,然后把人和空隙按从小到大排序。

用并查集维护四面墙之间是否能互相隔断。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ;
const int M = ;
const double eps = 1e-;
template<typename T>
inline void read(T&x)
{
T f = ,c = ;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){c=c*+ch-'';ch=getchar();}
x = f*c;
}
int n,m,X[],Y[],ff[N];
double W,H;
int findff(int x){return x==ff[x]?x:ff[x]=findff(ff[x]);}
struct Tree
{
double x,y,r;
void rd(){scanf("%lf%lf%lf",&x,&y,&r);}
}t[N];
double sqr(double k){return k*k;}
double dis(int i,int j){return sqrt(sqr(t[i].x-t[j].x)+sqr(t[i].y-t[j].y));}
int tot;
struct Hole
{
double k;
int x,y;
Hole(){}
Hole(double k,int x,int y):k(k),x(x),y(y){}
}h[N*N];
bool cmp(Hole a,Hole b){return a.k<b.k;}
int ans[M];
struct Peo
{
double r;
int c,id;
void rd(int i){scanf("%lf",&r),r*=;read(c),c--;id=i;}
}p[M];
bool vmp(Peo a,Peo b){return a.r<b.r;}
void merge(int x,int y)
{
x = findff(x),y = findff(y);
if(x!=y)ff[x]=y;
}
bool cX(){return findff(X[])==findff(X[]);}
bool cY(){return findff(Y[])==findff(Y[]);}
int Xi[]={,,,},Yi[]={,,,};
bool cC(int cn){return findff(X[Xi[cn]])==findff(Y[Yi[cn]]);}
void ot(int x)
{
for(int i=;i<;i++)if(ans[x]&(<<i))
putchar(''+i);
puts("");
}
int main()
{
read(n),read(m);
scanf("%lf%lf",&W,&H);
X[] = n+,X[] = n+,Y[] = n+,Y[] = n+;
for(int i=;i<=n+;i++)ff[i]=i;
for(int i=;i<=n;i++)
{
t[i].rd();
h[++tot] = Hole(t[i].x-t[i].r,i,Y[]);
h[++tot] = Hole(t[i].y-t[i].r,i,X[]);
h[++tot] = Hole(W-t[i].x-t[i].r,i,Y[]);
h[++tot] = Hole(H-t[i].y-t[i].r,i,X[]);
}
for(int i=;i<=n;i++)for(int j=i+;j<=n;j++)
h[++tot] = Hole(dis(i,j)-t[i].r-t[j].r,i,j);
for(int i=;i<=m;i++)p[i].rd(i);
sort(p+,p++m,vmp),sort(h+,h++tot,cmp);
for(int i=,j=;i<=m;i++)
{
while(h[j].k+eps<p[i].r&&j<=tot)
merge(h[j].x,h[j].y),j++;
bool cx = cX(),cy = cY();int cc = p[i].c;
if(cC(cc)){ans[p[i].id]=(<<cc);continue;}
if(cx&&cy)ans[p[i].id]=(<<cc);
else if(cx&&!cy)ans[p[i].id]=((<<cc)|(<<(cc^)));
else if(!cx&&cy)ans[p[i].id]=((<<cc)|(<<(cc^)));
else ans[p[i].id]=;
for(int cn=;cn<;cn++)
if(cC(cn)&&(ans[p[i].id]&(<<cn)))ans[p[i].id]^=(<<cn);
}
for(int i=;i<=m;i++)ot(i);
return ;
}

最新文章

  1. SCNU ACM 2016新生赛决赛 解题报告
  2. 转:solr6.0配置中文分词器IK Analyzer
  3. Null 与 “” 的区别
  4. 【AngularJs】---&quot;Error: [ng:areq] Argument &#39;fn&#39; is not a function, got undefined&quot;
  5. 从 Android 静音看正确的查找 bug 的姿势
  6. jedis异常:NoSuchElementException: Timeout waiting for idle object
  7. Android -- onMeasure()源码分析
  8. 产生AJAX跨域问题的原因
  9. 20162321王彪-实验二-Java面向对象程序设计
  10. 虚拟机linux挂载光盘显示:mount: you must specify the filesystem type
  11. cookie session token
  12. iOS学习——页面的传值方式
  13. JSON.stringify() 和 JSON.parse()
  14. 弹性(flex)布局
  15. M1-Flask-Day3
  16. Lintcode214-Max of Array-Naive
  17. href=&quot;javascript:void(0)&quot; 的用法
  18. Android弹出Dialog使用举例
  19. Django之urls.py详解
  20. supervisord的配置

热门文章

  1. 在linux下pycharm无法输入中文
  2. ISCC 2018线上赛 writeup
  3. Zju1610 Count the Colors(lazy标记详解)
  4. Java语言和虚拟机规范下载
  5. nginx 设置websocket支持
  6. 三维BFS Poj 2251
  7. urllib库的基本使用
  8. Codeforces Round #396 (Div. 2) A
  9. ORA-00972_标识符过长
  10. 解决thymeleaf严格html5校验的方法