题意:给你一些线段,问与第i根线段相交的线段有几根。。
思路:计算几何+并查集
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N = 1009;
const double INF = 1e20 , EPS = 1E-6;
bool zero(double x){
return -EPS<x&&x<EPS;
}
struct cvector{
double x,y;
cvector(){};
cvector(double a,double b){x=a,y=b;}
};
double operator^(cvector p,cvector q){
return p.x*q.y-q.x*p.y;
}
double operator *(cvector p,cvector q){
return p.x*q.x+p.y*q.y;
}
struct cpoint{
double x,y;
cpoint(double a,double b){
x = a,y = b;
}
cpoint(){}
};
cvector operator -(cpoint a, cpoint b){ ///向量ab
return cvector(b.x-a.x, b.y-a.y);
}
struct cline{
cpoint a,b;
} re[N];
bool dots_inline(cpoint p1,cpoint p2,cpoint p3){///判三点共线
return zero((p2-p1)^(p3-p1));
}
bool same_side(cpoint p1,cpoint p2,cline l){ ///两点在线段同侧
cvector v0=l.b-l.a;
cvector v1=p1-l.a,v2=p2-l.a;
return (v1^v0)*(v2^v0)>EPS;
}
bool dot_onseg(cpoint p,cline ll){ /// 点在线段上
if(!dots_inline(p,ll.a,ll.b)) return false;
cvector v1=ll.b-ll.a,v2=p-ll.a;
cvector v3=ll.a-ll.b,v4=p-ll.b;
if(v1*v2>-EPS&&v3*v4>-EPS) return true;
return false;
}
bool intersect_in(cline u,cline v){ ///线段相交,包括交点和重合
if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
return dot_onseg(u.a,v)||dot_onseg(u.b,v)
||dot_onseg(v.a,u)||dot_onseg(v.b,u);
}
int fa[N];
int finfa(int k)
{
if(fa[k]==k) return k;
return fa[k] = finfa(fa[k]);
}
void un(int a,int b)
{
fa[finfa(a)] = fa[finfa(b)];
}
bool xx(int a,int b)
{
return intersect_in(re[a],re[b]);
}
int main()
{
freopen("in.txt","r",stdin);
int cas,ou=0,n,tmp,cnt;
char ar[3];
cpoint a,b;
scanf("%d",&cas);
while(cas--)
{
cnt = 0;
if(ou) printf("\n");ou = true;
scanf("%d",&n);
for(int i=0;i<=n;i++) fa[i] = i;
while(n--)
{
scanf("%s",ar);
if(ar[0]=='P')
{
scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
re[cnt].a=a,re[cnt].b=b;
for(int i=0;i<cnt;i++)
{
if(finfa(i)!=finfa(cnt)&&xx(i,cnt))
{
un(i,cnt);
}
}cnt++;
}
else
{
scanf("%d",&tmp);tmp--;
//cout<<tmp<<" "<<cnt<<endl;
int f = finfa(tmp),ans = 0;
for(int i=0;i<cnt;i++)
if(finfa(i)==f) ans++;
printf("%d\n",ans);
}
}
}
return 0;
}