hdu1558

计算几何+并查集,就是给你一堆线段,问任意一条的所在的集合(直接相交或
间接相交为同一集合)的线段条数;
用叉积来判断是否相交
用并查集来查找和计算线段的条数

 

#include<iostream>
typedef struct piont
{
double x;
double y;
}piont;
typedef struct s
{
piont p1;
piont p2;
int father;
int high;
}s;
s bin[1005];
double cross(piont o,piont a,piont b)
{
return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
}
double min(double a,double b)
{
if(a>b)
return b;
else
return a;
}
double max(double a,double b)
{
if(a>b)
return a;
else
return b;
}
int onseg(piont a,piont b,piont c)
{
if(c.x>=min(a.x,b.x)&&c.x<=max(a.x,b.x)&&c.y<=max(a.y,b.y)&&c.y>=min(a.y,b.y))
return 1;
else
return 0;
}
int intersect(s A,s B)
{
double d1,d2,d3,d4;
d1=cross(A.p1,A.p2,B.p1);
d2=cross(A.p1,A.p2,B.p2);
d3=cross(B.p1,B.p2,A.p1);
d4=cross(B.p1,B.p2,A.p2);
if(((d1<0&&d2>0)||(d1>0&&d2<0))&&((d3<0&&d4>0)||(d3>0&&d4<0)))
return 1;
else if(0==d1&&onseg(A.p1,A.p2,B.p1))
return 1;
else if(0==d2&&onseg(A.p1,A.p2,B.p2))
return 1;
else if(0==d3&&onseg(B.p1,B.p2,A.p1))
return 1;
else if(0==d4&&onseg(B.p1,B.p2,A.p2))
return 1;
else
return 0;
}
int find(int a)
{
while(bin[a].father!=a)
a=bin[a].father;
return a;
}
void merge(int a,int b)
{
int fa,fb;
fa=find(a);
fb=find(b);
if(fa!=fb)
{
if(bin[fa].high>=bin[fb].high)
{
bin[fb].father=fa;
bin[fa].high+=bin[fb].high;
}
else
{
bin[fa].father=fb;
bin[fb].high+=bin[fa].high;
}
}
}
int main()
{
int t,n,i,m,j,u;
char ch;
scanf("%d",&t);
while(t--)
{
m=0;
for(i=1;i<=1000;i++)
{
bin[i].father=i;
bin[i].high=1;
}
scanf("%d",&n);getchar();
for(i=1;i<=n;i++)
{
ch=getchar();
if(ch=='P')
{
m++;
scanf("%lf %lf %lf %lf",&bin[m].p1.x,&bin[m].p1.y,&bin[m].p2.x,&bin[m].p2.y);getchar();
bin[m].father=m;
bin[m].high=1;
for(j=1;j<m;j++)
{
if(intersect(bin[j],bin[m]))
{
merge(j,m);
}
}
}
else
{
scanf("%d",&u);getchar();
u=find(u);
printf("%d\n",bin[u].high);
}
}
if(t)
printf("\n");
}
return 0;
}

 

你可能感兴趣的:(D)