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
题意是给你n次操作,如果输入了P 那么就输入一条线段的两个端点坐标 x1,y1,x2,y2。 如果为 Q操作,那么 Q num 表示和num这条线段直接或间接相交的有多少条线段。
对于这道题来说并查集的应用并不多,只用单独开一个nu[i]来记录以i为父亲的节点有多少个,在插入的时候更新即可,问题在于判断相交,至今对判断方法不太清楚,借用了别人的函数。
#include"iostream"
#include"cstring"
#include"cstdio"
#include"cmath"
#include"algorithm"
#define eps 1e-10
using namespace std;
struct Point
{
double x,y;
};
struct Line
{
Point a,b;
}line[1005];
int fa[1005];
int nu[1005];
void init()
{
for(int i = 0;i < 1005;i++) fa[i] = i;
for(int i = 0;i < 1005;i++) nu[i] = 1;
}
int find_fa(int x)
{
if(x == fa[x]) return x;
fa[x] = find_fa(fa[x]);
return fa[x];
}
void add(int x,int y)
{
int fx = find_fa(x);
int fy = find_fa(y);
if(fx == fy) return;
fa[fx] = fy;
nu[fy] += nu[fx];
nu[fx] = 0;
}
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));
}
int intersect(Line u,Line 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(void)
{
int T;
scanf("%d",&T);
for(int cas = 1;cas <= T;cas++)
{
init();
int n;
int num = 0;
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
char typ;
cin >> typ;
if(typ == 'P')
{
num++;
scanf("%lf %lf %lf %lf",&line[num].a.x,&line[num].a.y,&line[num].b.x,&line[num].b.y);
for(int j = 1;j < num;j++)
{
if(intersect(line[j],line[num]) != 0)
{
add(j,num);
}
}
}
if(typ == 'Q')
{
int xx;
scanf("%d",&xx);
int aa = find_fa(xx);
printf("%d\n",nu[aa]);
}
}
if(cas != T) printf("\n");
}
return 0;
}