【bzoj5183】[Baltic2016]Park 离线+对偶图+并查集
题目描述
输入
输出
样例输入
5 3
16 11
11 8 1
6 10 1
7 3 2
10 4 1
15 5 1
1 1
2 2
2 1
样例输出
1234
2
14
题解
离线+对偶图+并查集
套路:如果两棵树或树与边界之间无法通过,则视作它们之间连了一条边。
那么左下角能到右下角等价于:下边界与左、上、右边界都不连通。其余同理。
然而每个人的半径都不同,对每个人单独处理必T无疑。考虑离线,将人按照半径、树与树和树与边界按照能通过的最大距离从小到大排序然后处理即可。
连通性可以直接使用并查集维护。
时间复杂度 $O(n^2\log n+m\log m+m\times 常数)$
#include <cmath>
#include <cstdio>
#include <algorithm>
#define squ(x) (x) * (x)
using namespace std;
struct data
{
double d;
int x , y;
data() {}
data(double a , int b , int c) {d = a , x = b , y = c;}
bool operator<(const data &a)const {return d < a.d;}
}a[2007010] , q[100010];
double px[2010] , py[2010] , pr[2010];
int f[2010] , ans[100010] , tot;
int find(int x)
{
return x == f[x] ? x : f[x] = find(f[x]);
}
int main()
{
int n , m , i , j , p = 1 , t1 , t2 , t3 , t4;
double w , h;
scanf("%d%d%lf%lf" , &n , &m , &w , &h);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%lf%lf%lf" , &px[i] , &py[i] , &pr[i]);
a[++tot] = data(px[i] - pr[i] , i , n + 1);
a[++tot] = data(py[i] - pr[i] , i , n + 2);
a[++tot] = data(w - px[i] - pr[i] , i , n + 3);
a[++tot] = data(h - py[i] - pr[i] , i , n + 4);
for(j = 1 ; j < i ; j ++ ) a[++tot] = data(sqrt(squ(px[i] - px[j]) + squ(py[i] - py[j])) - pr[i] - pr[j] , i , j);
}
for(i = 1 ; i <= m ; i ++ ) scanf("%lf%d" , &q[i].d , &q[i].x) , q[i].d *= 2 , q[i].y = i;
sort(a + 1 , a + tot + 1) , sort(q + 1 , q + m + 1);
for(i = 1 ; i <= n + 4 ; i ++ ) f[i] = i;
for(i = 1 ; i <= m ; i ++ )
{
while(p <= tot && a[p].d < q[i].d) f[find(a[p].x)] = find(a[p].y) , p ++ ;
t1 = find(n + 1);
t2 = find(n + 2);
t3 = find(n + 3);
t4 = find(n + 4);
if(q[i].x == 1)
{
ans[q[i].y] |= (1 << 1);
if(t2 != t1 && t2 != t3 && t2 != t4) ans[q[i].y] |= (1 << 2);
if(t1 != t2 && t1 != t3 && t2 != t4 && t3 != t4) ans[q[i].y] |= (1 << 3);
if(t1 != t2 && t1 != t3 && t1 != t4) ans[q[i].y] |= (1 << 4);
}
else if(q[i].x == 2)
{
ans[q[i].y] |= (1 << 2);
if(t2 != t1 && t2 != t3 && t2 != t4) ans[q[i].y] |= (1 << 1);
if(t3 != t1 && t3 != t2 && t3 != t4) ans[q[i].y] |= (1 << 3);
if(t1 != t3 && t1 != t4 && t2 != t3 && t2 != t4) ans[q[i].y] |= (1 << 4);
}
else if(q[i].x == 3)
{
ans[q[i].y] |= (1 << 3);
if(t1 != t2 && t1 != t3 && t2 != t4 && t3 != t4) ans[q[i].y] |= (1 << 1);
if(t3 != t1 && t3 != t2 && t3 != t4) ans[q[i].y] |= (1 << 2);
if(t4 != t1 && t4 != t2 && t4 != t3) ans[q[i].y] |= (1 << 4);
}
else
{
ans[q[i].y] |= (1 << 4);
if(t1 != t2 && t1 != t3 && t1 != t4) ans[q[i].y] |= (1 << 1);
if(t1 != t3 && t1 != t4 && t2 != t3 && t2 != t4) ans[q[i].y] |= (1 << 2);
if(t4 != t1 && t4 != t2 && t4 != t3) ans[q[i].y] |= (1 << 3);
}
}
for(i = 1 ; i <= m ; i ++ )
{
for(j = 1 ; j <= 4 ; j ++ )
if(ans[i] & (1 << j))
printf("%d" , j);
puts("");
}
return 0;
}
【bzoj5183】[Baltic2016]Park 离线+对偶图+并查集的更多相关文章
- 【bzoj3007】拯救小云公主  二分+对偶图+并查集
		
题目描述 英雄又即将踏上拯救公主的道路…… 这次的拯救目标是——爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意识到自己还是等 ...
 - bzoj5183 [Baltic2016]Park
		
题目描述: bz luogu 题解: 把坐标系看反了持续$WA$系列. 对偶图+并查集维护. 先处理出树对树.树对墙的空隙,然后把人和空隙按从小到大排序. 用并查集维护四面墙之间是否能互相隔断. 代码 ...
 - BZOJ_4423_[AMPPZ2013]Bytehattan_对偶图+并查集
		
BZOJ_4423_[AMPPZ2013]Bytehattan_对偶图+并查集 Description 比特哈顿镇有n*n个格点,形成了一个网格图.一开始整张图是完整的. 有k次操作,每次会删掉图中的 ...
 - 【BZOJ4423】[AMPPZ2013]Bytehattan 对偶图+并查集
		
[BZOJ4423][AMPPZ2013]Bytehattan Description 比特哈顿镇有n*n个格点,形成了一个网格图.一开始整张图是完整的.有k次操作,每次会删掉图中的一条边(u,v), ...
 - 【bzoj4423】[AMPPZ2013]Bytehattan(平面图转对偶图+并查集)
		
题目传送门:bzoj4423 如果是普通的删边判连通性,我们可以很显然的想到把操作离线下来,倒着加边.然而,这题强 制 在 线. 虽然如此,但是题目所给的图是个平面图.那么我们把它转成对偶图试试看? ...
 - HDU 5441 离线处理 + 并查集
		
题意:给n个节点m条带权值边的无向图.然后q个问题,每次询问点对的数目,点对需要满足的条件是:1)连通:2)其路径的最大权值不能超过询问值. 分析:如果没次询问一次,dfs一次,很可能超时,因此可以用 ...
 - 对偶图 并查集  BZOJ4423
		
题目链接 题目因为要根据上一次的输出结果来判断这次的输入,也就是要求我们强制在线,不能够把输入全部储存后处理 如果不要求强制在线,我们可以先把所以输入储存起来,从最后开始处理,把删边改成加边,如果在加 ...
 - [BZOJ4423][AMPPZ2013]Bytehattan(对偶图+并查集)
		
建出对偶图,删除一条边时将两边的格子连边.一条边两端连通当且仅当两边的格子不连通,直接并查集处理即可. #include<cstdio> #include<algorithm> ...
 - hdu Portal(离线,并查集)
		
题意:在一张无向图上,已知边权,做q组询问,问小于L的点对共有几组.点对间的距离取=min(两点之间每一条通路上的最大值). 分析:这里取最大值的最小值,常用到二分.而这里利用离线算法,先对边从小到大 ...
 
随机推荐
- 从原理到代码:大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社
			
从原理到代码:大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社 PPT链接: https://pan.baidu.com/s/1i5Jrr1N 视频链接: https: ...
 - HBase核心功能模块--读书笔记
			
客户端Client 客户端 Client 是整个 HBase 系统的入口.使用者直接通过客户端操作 HBase.客户端 使用 HBase 的 RPC 机制与 HMaster 和 RegionServe ...
 - (转) 转换Drupal7模块到Drupal8
			
转载地址:http://verynull.com/2015/11/02/Converting-7-x-modules-to-8-x/ 本节主要介绍如何把drupal7的模块转化为drupal8.参考资 ...
 - js创建对象 object.create()用法
			
Object.create()方法是ECMAScript 5中新增的方法,这个方法用于创建一个新对象.被创建的对象继承另一个对象的原型,在创建新对象时可以指定一些属性. 语法: Object.crea ...
 - C#之#if #endif的简单用法
			
有时候我们看到别人的代码中有#if #endif,其实这是通过不同版本来选择运行哪段代码,和咱们的if,else是一样的.下面看下简单的用法 #if DEBUG txt_display.Text = ...
 - MES与ERP的区别(转)
			
MES和ERP有很大的不同,主要体现在以下几个方面: 1.管理的目标不同 ERP的重点在于财务,也就是从财务的角度出发来对企业的资源进行计划,相关的模块也是以财务为核心的展开,最终的管理数据也是集中到 ...
 - 原生 js 简单实现 Promise
			
写在思否,欢迎各位大佬给出建议: https://segmentfault.com/a/1190000018530433
 - 韦大仙--LoadRunner压力测试:详细操作流程
			
一. 录制脚本 1.安装完毕后,创建脚本: 点击OK之后,会弹出网址,之后创建Action,每进一个页面添加一个Action,录制结束后,终止录制. 二. 修改脚本 1.脚本参数化 将登录的用户名密码 ...
 - oracle数据库之组函数
			
组函数也叫聚合函数,用来对一组值进行运算,并且可以返回单个值 常见的组函数: (1)count(*),count(列名) 统计行数:找到所有不为 null 的数据来统计行数 (2)avg(列名) ...
 - JavaScript事件冒泡和捕获
			
事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件. 事件冒泡是自下而上的去触发事件. 绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获.true,事件捕获:fa ...