题目链接

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

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

 //
#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. oracle 查询今天哪个表增加的数据多

    一.创建一个表  create table A(  TABLE_NAME VARCHAR2(200),  COUNT_NUM  NUMBER) 二.创建一个存储过程create or replace  ...

  2. [CentOS 6.5 X64]讓firefox java plugin 啟動

    到ORACLE下載JRE http://www.oracle.com/technetwork/java/javase/downloads/index.html 我是X64所以下載 jre-7-linu ...

  3. homework-07 C++ 11 能好怎

    大二时候学过c++,但是那只是为了考试在学习,大作业也就写了一个读写者线程同步的模拟,连一个完整的类都没有写过,所以我必须承认对c++了解的很少. 对于C++ 11这一新标准,我首先阅读了来自前C++ ...

  4. 利用FormsAuthentication.RedirectFromLoginPage进行身份验证

    web.config中: <authentication>节 格式: <authentication mode="Forms">    //I.Window ...

  5. 高效线程池(threadpool)的实现

    高效线程池(threadpool)的实现 Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线 ...

  6. MSSQL Transaction[事务] and Procedure[存储过程]

    --事务分三种 --1.显示事务 --我们手动begin transaction ...... commit transaction/rollback transaction --上面这种写法叫做“显 ...

  7. js之内置对象

    内置对象(Global和Math):JS程序在执行之前就已经存在,开发人员不必再取实例化的内置对象 下面对Global对象进行介绍一下,Math用的不多就不做介绍了 1.Global对象 Global ...

  8. 《实时控制软件设计》Git 基本操作练习

    根据老师提供的教程 对 数据库创建.提交文件.创建分支.删除分支.合并分支.冲突处理等操作进行了练习 得到log文件如下: yanbin-guo@yanbinguo MINGW64 /Git (mas ...

  9. HashCode作用

    作用: 1.HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定镀锡的存储地址的 2.如果两个对象的equals相等,那么HashCode一定相等,反之不行 3.如 ...

  10. mysql 慢查询开启

    相关博客: linux下开启mysql慢查询,分析查询语句 开启方法: 方法一:使用命令开启慢查询开启 mysql> show variables like "%long%" ...