题目链接

题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出。

思路 : 先判断与其他线段是否相交,然后合并。

 //
#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 (并查集+线段非规范相交)的更多相关文章

  1. hdu 1558 Segment set (并查集)

    Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  2. hdu 1558 Segment set 计算几何+并查集★

    #include <cstdio> #include <iostream> #include <string.h> using namespace std; ; # ...

  3. UVA1455 - Kingdom(并查集 + 线段树)

    UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...

  4. HDU 1811 拓扑排序 并查集

    有n个成绩,给出m个分数间的相对大小关系,问是否合法,矛盾,不完全,其中即矛盾即不完全输出矛盾的. 相对大小的关系可以看成是一个指向的条件,如此一来很容易想到拓扑模型进行拓扑排序,每次检查当前入度为0 ...

  5. hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)

    hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...

  6. 并查集&线段树&树状数组&排序二叉树

    超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...

  7. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  8. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  9. HDU 1558 Segment set( 判断线段相交 + 并查集 )

    链接:传送门 题意:输入一个数 n 代表有 n 组操作,P 是在平面内加入一条线段,Q x 是查询第 x 条线段所在相交集合的线段个数 例如:下图 5 与 1.2 相交,1 与 3 相交,2 与 4 ...

随机推荐

  1. 关于生成缩略图及水印图片时出现GDI+中发生一般性错误解决方法

    System.Drawing.Image OldImage = null; oldImage = System.Drawing.Image.FromFile(ImageUrl); 使用该方法读取图片时 ...

  2. 说说oracle中的面向对象与面向集合

    这一篇算是对近期自己学习的一个心得总结 一.oracle的面向对象 SQL是面向集合的这个大家都知道,但是不可否认现在的oracle中有很多地方都体现着面向对象的思维.(这也算是各大语言殊途同归的一个 ...

  3. iTiTa再次回归,这一年我们都在干什么?

    转眼一看这都2013年了,距离我们上一次发布篮球游戏已经一年多了. 从去年到今年我们几乎只做了一件事——<二战前线>! 这一年的时间从最简单的游戏游戏雏形到今天一个具备商业能力的游戏,一路 ...

  4. 【分享】生成带数据的Insert语句工具(源码)

    这个工具用于导出带数据的Insert语句,方便在不同版本的数据库上导出数据.有人说sql server 2008自带导出带数据的Insert语句(连接)但是我的数据库版本没有这个选项,无奈之下自己简单 ...

  5. 如何安装altium designer 10

    http://jingyan.baidu.com/article/4dc4084881e2bdc8d946f1f3.html

  6. C++类中的this指针的作用

    1.我们知道C++的类成员函数中,默认都隐含了一个this指针,标识调用该成员函数的对象 2.为什么需要有一个this指针呢?C++设计这个机制的初衷是什么呢? 我们知道,普通的C++类,其成员函数是 ...

  7. Windows Live Writer教程及代码高亮工具

    十分感谢六仙庵对于Windows Live Writer的教程,方便了编辑与发布,教程地址如下: http://www.cnblogs.com/liuxianan/archive/2013/04/13 ...

  8. 四则运算(2)之软件单元测试:Right-BICEP

    一.Right-BICEP主要测试以下几方面的问题: Right-结果是否正确? B-是否所有的边界条件都是正确的? I-能查一下反向关联吗? C-能用其他手段交叉检查一下结果吗? E-你是否可以强制 ...

  9. Grails 1.2参考文档速读(10):Controller

    转载:http://keyvalue.blog.51cto.com/1475446/303260       从本篇起,我们将开始进入Grails的Web层,首先让我们从Controller说起. G ...

  10. Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题

    Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字 ...