ccsu1359 木棒相交 (叉积线段判交,并查集判断是否属于同一个集合)
题意:判断n条木棒中木棒a是否与木棒b相交。其中木棒的相交具有传递性。
首先用一个判断线段是否相交的函数判断相交:
struct Point
{double x;double y;
};
typedef struct Point point;
Const int easp=1e-9;
//叉积
double multi(point p0, point p1, point p2) //根据斜率:y2/x2 - y1/x2!=0则相交
{ //根据p1点在线段p0 p2的哪一侧,若线段中两点p1 p3分别在p0 p2两侧,则必定线段相交。return ( p1.x - p0.x )*( p2.y - p0.y )-( p2.x - p0.x )*( p1.y - p0.y );
}
//相交返回true,否则为false, 接口为两线段的端点
bool isIntersected(point s1,point e1, point s2,point e2)
{return (max(s1.x,e1.x) >= min(s2.x,e2.x)) &&(max(s2.x,e2.x) >= min(s1.x,e1.x)) &&(max(s1.y,e1.y) >= min(s2.y,e2.y)) &&(max(s2.y,e2.y) >= min(s1.y,e1.y)) &&(multi(s1,s2,e1)*multi(s1,e1,e2)>=0) &&(multi(s2,s1,e2)*multi(s2,e2,e1)>=0);
}
然后解决相交的 传递性:
用并查集解: 用一个数组fa[1010]存储每条线段的相交的起始点。即若1与3、5相交,而3与6、8相交,则6的fa为3,但是6的起始相交点为3的fa即1,8同理。若1与3、5相交,而2与7、9、4相交,而5与9相交,则需要找到5与9两者的起始点,让任意一个起始点的fa等于另一个起始点(将两者联系起来)。
并查集的相关学习:(引自:Cherish_yimi)
l 并查集:(union-find sets)
一种简单的用途广泛的集合. 并查集是若干个不相交集合,能够实现较快的合并和判断元素所在集合的操作,应用很多,如其求无向图的连通分量个数等。最完美的应用当属:实现Kruskar算法求最小生成树。
l 并查集的精髓(即它的三种操作,结合实现代码模板进行理解):
1、Make_Set(x) 把每一个元素初始化为一个集合
初始化后每一个元素的父亲节点是它本身,每一个元素的祖先节点也是它本身(也可以根据情况而变)。
2、Find_Set(x) 查找一个元素所在的集合
查找一个元素所在的集合,其精髓是找到这个元素所在集合的祖先!这个才是并查集判断和合并的最终依据。
判断两个元素是否属于同一集合,只要看他们所在集合的祖先是否相同即可。
合并两个集合,也是使一个集合的祖先成为另一个集合的祖先,具体见示意图
3、Union(x,y) 合并x,y所在的两个集合
合并两个不相交集合操作很简单:
利用Find_Set找到其中两个集合的祖先,将一个集合的祖先指向另一个集合的祖先。如图
l 并查集的优化
1、Find_Set(x)时 路径压缩
寻找祖先时我们一般采用递归查找,但是当元素很多亦或是整棵树变为一条链时,每次Find_Set(x)都是O(n)的复杂度,有没有办法减小这个复杂度呢?
答案是肯定的,这就是路径压缩,即当我们经过"递推"找到祖先节点后,"回溯"的时候顺便将它的子孙节点都直接指向祖先,这样以后再次Find_Set(x)时复杂度就变成O(1)了,如下图所示;可见,路径压缩方便了以后的查找。
2、Union(x,y)时 按秩合并
即合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小。
ccsu1359 木棒相交 (叉积线段判交,并查集判断是否属于同一个集合)相关推荐
- (线段判交的一些注意。。。)nyoj 1016-德莱联盟
1016-德莱联盟 内存限制:64MB 时间限制:1000ms 特判: No 通过数:9 提交数:9 难度:1 题目描述: 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我 ...
- BZOJ4399魔法少女LJJ——线段树合并+并查集
题目描述 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了 LJJ感叹道"这里真是个迷人的绿色世界,空气清新.淡雅,到处散发着醉 ...
- c++自带的可持久化平衡树?rope大法好!(超详细解答 + 5道例题讲解,可直接替代可持久化的线段树、并查集、平衡树!)
整理的算法模板合集: ACM模板 目录 c++自带的可持久化平衡树?rope大法好! 1. 声明 2. 支持操作 char类型的rope int类型的rope 3. 具体的细节 4. "可持 ...
- bzoj4025-二分图【线段树分治,并查集】
正题 题目链接:https://darkbzoj.tk/problem/4025 题目大意 nnn个点mmm条边,每条边会在一个TTT以内的时间段内出现,对于任意一个TTT以内的时刻求图是否是一个二分 ...
- CodeForces - 1217F Forced Online Queries Problem(线段树分治+并查集撤销)
题目链接:点击查看 题目大意:给出 nnn 个点,初始时互相不存在连边,需要执行 mmm 次操作,每次操作分为两种类型: 1xy1 \ x \ y1 x y:如果 (x,y)(x,y)(x,y) 之间 ...
- 牛客多校8 - All-Star Game(线段树分治+并查集按秩合并的撤销操作)
题目链接:点击查看 题目大意:有 n 个球员和 m 个球迷,一个球员可能是多个球迷的粉丝,需要选择最少的球员进行比赛,使得所有的球迷都愿意观看(对于每个球迷来说,都有至少一个其喜欢的球员入选比赛) 对 ...
- “美登杯”上海市高校大学生程序设计 C. 小花梨判连通 (并查集+map)
Problem C C . 小 花梨 判连通 时间限制:2000ms 空间限制:512MB Description 小花梨给出?个点,让?位同学对这?个点任意添加无向边,构成?张图.小花梨想知道对于 ...
- [NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)
[NOI2018] 归程 description solution1 code1 solution2 code description 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要 ...
- Codeforces 1140F 线段树 分治 并查集
题意及思路:https://blog.csdn.net/u013534123/article/details/89010251 之前cf有一个和这个相似的题,不过那个题只有合并操作,没有删除操作,直接 ...
最新文章
- 机器学习从Python 2迁移到Python 3,你需要注意的一些事……
- android webview开启html5支持
- 如何批量创建网页的快捷方式
- postgresql 10.1 分区表之 list 分区
- MFC用代码创建工具栏
- PHP多进程编程初步
- Airflow 中文文档:概念
- 嵌入式linux 实现mdev SD卡和U盘自动挂载和卸载的方法 mdev.conf
- [转] ROS-I simple_message 源码分析:MessageManager
- Ubuntu 软件包管理详解
- 第十五章 iptables
- 1g的树莓派4b能做什么_树莓派4B系统安装及配置
- Scala中class、object、case class、case object区别
- java反编译 jd-gui_JD-GUI(Java反编译工具)
- 樊昌信 通信原理第七版 第十一章 思考题答案
- Android学习之ExpandableListView
- Unity不规则按钮
- 【日常技巧】小米手机投屏至win10笔记本
- Seurat | 强烈建议收藏的单细胞分析标准流程(基础质控与过滤)(一)
- 康威定律【系统设计的影响因素】