p时把新的线段添加进来,Q时输出与对应编号的线段同一个集合的线段数目输出。用到并查集和判断线段是否相交。
#include <iostream>
#include <cmath>
using namespace std;
#define MAX 1005
#define pre 0.000000001
struct Node
{
double x, y;
};
struct Line
{
Node s, e;
};
Line line[MAX];
int p[MAX];
int n, m;
char ch;
int find(int x)
{
return x==p[x] ? x : p[x]=find(p[x]);
}
int dblcmp(double b)
{
if (fabs(b) < pre)
return 0;
return b > 0 ? 1 : -1;
}
int cross(Node a, Node b, Node c)
{
double x1 = a.x -c.x;
double y1 = a.y - c.y;
double x2 = b.x - c.x;
double y2 = b.y - c.y;
return x1 * y2 - x2 * y1;
}
int segcrossSimple(Line a, Line b)//判断两直线是否相交
{
int x1 = dblcmp(cross(a.s, a.e, b.s));
int x2 = dblcmp(cross(a.s, a.e, b.e));
int y1 = dblcmp(cross(b.s, b.e, a.s));;
int y2 = dblcmp(cross(b.s, b.e, a.e));
return (x1 * x2 <= 0) && (y1 * y2 <= 0);
}
int main()
{
int flag = 1;
cin>>n;
while (n--)
{
cin>>m;
int j = 1;
for (int i=1; i<=m; i++)
p[i] = i;
for (int i=1; i<=m; i++)
{
cin>>ch;
if (ch=='P')
{
cin>>line[j].s.x>>line[j].s.y>>line[j].e.x>>line[j].e.y;
for (int k=1; k<=j; k++)
if (segcrossSimple(line[j], line[k]))
{
int x = find(j);
int y = find(k);
if (x!=y)
p[x] = y;
}
j++;
}
else
{
int r, ans = 0;
cin>>r;
int fa = find(r);
for (int k=1; k<=j; k++)
if (find(k)==fa)
ans++;
cout<<ans<<endl;
}
}
if (n)
cout<<endl;
}
return 0;
}