HDU 1558 Segment set (并查集+线段非规范相交)
题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出。
思路 : 先判断与其他线段是否相交,然后合并。
//
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#define eps 1e-8
#define zero(x) (((x) > 0 ? (x) : (-x)) < eps) using namespace std ; struct point
{
double x,y ;
} p[];
struct Line
{
point a;
point b ;
// int num ;
} L[] ;
int father[],numb[],rankk[] ;
int cnt ;
double direction(point p0,point p1,point p2)
{
return (p2.x-p0.x)*(p1.y-p0.y)-(p1.x-p0.x)*(p2.y-p0.y);
} bool on_segment(point p0,point p1,point p2)
{
if((min(p0.x,p1.x)<=p2.x && p2.x<=max(p0.x,p1.x)) && (min(p0.y,p1.y)<=p2.y && p2.y<=max(p0.y,p1.y)))
return true;
return false;
} bool Segment_intersect(point p1,point p2,point p3,point p4)
{
double d1,d2,d3,d4;
d1 = direction(p3,p4,p1);
d2 = direction(p3,p4,p2);
d3 = direction(p1,p2,p3);
d4 = direction(p1,p2,p4);
if(((d1> && d2<)||(d1< && d2>)) && ((d3> && d4<)||(d3<&&d4>)))
return true;
else if((d1== && on_segment(p3,p4,p1)) || (d2== && on_segment(p3,p4,p2)) || (d3== && on_segment(p1,p2,p3)) || (d4== && on_segment(p1,p2,p4)))
return true;
return false;
}
int find_(int x)
{
if(father[x] != x)
father[x] = find_(father[x]) ;
return father[x] ;
} void mergee(int a, int b){
int fx = find_(a);
int fy = find_(b); if (fx != fy){
father[fy] = fx;
numb[fx] += numb[fy];
}
}
void Init()
{
cnt = ;
for(int i=; i<=; i++)
{
numb[i]=;
}
for(int i = ; i < ; i++)
father[i] = i ;
memset(rankk,,sizeof(rankk)) ;
}
int main()
{
int T ,n,ss;
scanf("%d",&T) ;
char s[] ;
while( T--)
{
scanf("%d",&n) ;
Init() ;
for(int i = ; i < n ; i++)
{
scanf("%s",s) ;
if(s[] == 'P')
{
cnt ++ ;
scanf("%lf %lf %lf %lf",&L[cnt].a.x,&L[cnt].a.y,&L[cnt].b.x,&L[cnt].b.y) ;
for(int j = ; j < cnt ; j ++)
if(find_(j) != find_(cnt) && Segment_intersect(L[j].a,L[j].b,L[cnt].a,L[cnt].b))
mergee(j,cnt) ;
}
else
{
scanf("%d",&ss) ;
printf("%d\n",numb[find_(ss)]) ;
}
}
if(T) printf("\n") ;
}
return ;
}
线段非规范相交1
double cross(point p0,point p1,point p2)
{
return (p2.x-p0.x)*(p1.y-p0.y)-(p1.x-p0.x)*(p2.y-p0.y);
} bool on_segment(point p0,point p1,point p2)
{
if((min(p0.x,p1.x)<=p2.x && p2.x<=max(p0.x,p1.x)) && (min(p0.y,p1.y)<=p2.y && p2.y<=max(p0.y,p1.y)))
return true;
return false;
} bool Segment_intersect(point p1,point p2,point p3,point p4)
{
double d1,d2,d3,d4;
d1 = cross(p3,p4,p1);
d2 = cross(p3,p4,p2);
d3 = cross(p1,p2,p3);
d4 = cross(p1,p2,p4);
if(((d1> && d2<)||(d1< && d2>)) && ((d3> && d4<)||(d3<&&d4>)))
return true;
else if((d1== && on_segment(p3,p4,p1)) || (d2== && on_segment(p3,p4,p2)) || (d3== && on_segment(p1,p2,p3)) || (d4== && on_segment(p1,p2,p4)))
return true;
return false;
}
线段非规范相交2
double cross(point a, point b, point c)
{
return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
} //aa, bb为一条线段两端点 cc, dd为另一条线段的两端点 相交返回true, 不相交返回false
bool intersect(point aa, point bb, point cc, point dd)
{
if ( max(aa.x, bb.x)<min(cc.x, dd.x) )
{
return false;
}
if ( max(aa.y, bb.y)<min(cc.y, dd.y) )
{
return false;
}
if ( max(cc.x, dd.x)<min(aa.x, bb.x) )
{
return false;
}
if ( max(cc.y, dd.y)<min(aa.y, bb.y) )
{
return false;
}
if ( cross(cc, bb, aa)*cross(bb, dd, aa)< )
{
return false;
}
if ( cross(aa, dd, cc)*cross(dd, bb, cc)< )
{
return false;
}
return true;
}
HDU 1558 Segment set (并查集+线段非规范相交)的更多相关文章
- hdu 1558 Segment set (并查集)
Segment set Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- hdu 1558 Segment set 计算几何+并查集★
#include <cstdio> #include <iostream> #include <string.h> using namespace std; ; # ...
- UVA1455 - Kingdom(并查集 + 线段树)
UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...
- HDU 1811 拓扑排序 并查集
有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的. 相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0 ...
- hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)
hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...
- 并查集&线段树&树状数组&排序二叉树
超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
- BZOJ 3910 并查集+线段树合并
思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...
- HDU 1558 Segment set( 判断线段相交 + 并查集 )
链接:传送门 题意:输入一个数 n 代表有 n 组操作,P 是在平面内加入一条线段,Q x 是查询第 x 条线段所在相交集合的线段个数 例如:下图 5 与 1.2 相交,1 与 3 相交,2 与 4 ...
随机推荐
- Android之通过向WebService服务器发送XML数据获取相关服务
原理图如下: 即客户端向WebService服务器通过HTTP协议发送XML数据(内部包含调用的一些方法和相关参数数据),然后WebService服务器给客户端返回一定的XML格式的数据 ...
- OSGi之Bundle
OSGi提出的根源是什么?在我看来就是对JVM的类加载机制进行了扩展,添加了一系列的规则,使得原有的类包(Class Package)扩展到类域(Class Domain).然后是建立在类域上的一系列 ...
- Go语言类型switch
switch还可以用于判断变量类型.使用方式为T.(type),即在变量后加上.(type).见代码: package main import ( "fmt" ) func mai ...
- html <input>标签类型属性type(file、text、radio、hidden等)详细介绍
html <input>标签类型属性type(file.text.radio.hidden等)详细介绍 转载请注明:文章转载自:[169IT-最新最全的IT资讯] html <inp ...
- ostream类重载的operator<<()函数
ostream类重载了operator<<()以识别不同的类型,如: int short long unsigned int unsigned short unsigned long f ...
- htop
apt-get install htop
- 拓展Jquery对象,实现Post提交并跳转
$.extend({ StandardPost:function(url,args){ var body = $(document.body), form = $("<form met ...
- 【Merge Sorted Array】cpp
题目: Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Not ...
- 【CentOS】安装jdk
问题描述: jdk安装与配置 (1)查看是否安装jdk --CentOS默认自带openjdk 先查看 rpm -qa | grep java 显示如下 ...
- short-path problem (Dijkstra) 分类: ACM TYPE 2014-09-01 23:51 111人阅读 评论(0) 收藏
#include <cstdio> #include <iostream> #include <cstring> using namespace std; cons ...