Description
A segment and all segments which are connected with it compose a segment set. The size of a segment set is the number of segments in it. The problem is to find the size of some segment set.

Input
In the first line there is an integer t - the number of test case. For each test case in first line there is an integer n (n<=1000) - the number of commands.
There are two different commands described in different format shown below:
P x1 y1 x2 y2 - paint a segment whose coordinates of the two endpoints are (x1,y1),(x2,y2).
Q k - query the size of the segment set which contains the k-th segment.
k is between 1 and the number of segments in the moment. There is no segment in the plane at first, so the first command is always a P-command.
There are two different commands described in different format shown below:
P x1 y1 x2 y2 - paint a segment whose coordinates of the two endpoints are (x1,y1),(x2,y2).
Q k - query the size of the segment set which contains the k-th segment.
k is between 1 and the number of segments in the moment. There is no segment in the plane at first, so the first command is always a P-command.
Output
For each Q-command, output the answer. There is a blank line between test cases.
Sample Input
1 10 P 1.00 1.00 4.00 2.00 P 1.00 -2.00 8.00 4.00 Q 1 P 2.00 3.00 3.00 1.00 Q 1 Q 3 P 1.00 4.00 8.00 2.00 Q 2 P 3.00 3.00 6.00 -2.00 Q 5
Sample Output
1 2 2 2 5
这道题判断线段相交的部分不太容易,感觉判断线段相交才是主要知识点的样子。。。
判断了线段相交,其实数据量也不大,两层for循环可解决。最后就是并查集,其实多开一个数组记录当前线段所属集合的线段数量就可以了。
刚开始忘了在更新线段数量之后更新整个集合的线段数量,检查花了点时间。
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int fa[1005],val[1005];
struct Point
{
double x,y;
};
struct node
{
Point a,b;
}po[1005];
int findd(int x)
{
if(x==fa[x])
return x;
fa[x]=findd(fa[x]);
val[x]=val[fa[x]];
return fa[x];
}
double multiply(Point p1,Point p2,Point p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
bool intersect(node u,node v)
{
return( (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&&
(max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&&
(max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&&
(max(v.a.y,v.b.y)>=min(u.a.y,u.b.y))&&
(multiply(v.a,u.b,u.a)*multiply(u.b,v.b,u.a)>=0)&&
(multiply(u.a,v.b,v.a)*multiply(v.b,u.b,v.a)>=0));
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,num=0;
scanf("%d",&n);
for(int i=0;i<=n;i++)
{
fa[i]=i;
val[i]=1;
}
for(int i=0;i<n;i++)
{
char s[2];
scanf("%s",s);
if(s[0]=='P')
{
node mid;
scanf("%lf%lf%lf%lf",&mid.a.x,&mid.a.y,&mid.b.x,&mid.b.y);
for(int j=0;j<num;j++)
{
if(intersect(mid,po[j]))
{
int id=findd(j);
if(fa[num]==num)
{
fa[num]=id;
val[id]+=val[num];
}
else
{
if(id!=fa[num])
{
fa[fa[num]]=id;
val[id]+=val[fa[num]];
}
}
findd(num);
}
}
po[num++]=mid;
}
else
{
int id;
scanf("%d",&id);
id=findd(id-1);
printf("%d\n",val[id]);
}
}
if(t)
printf("\n");
}
return 0;
}