Segment set
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5309 Accepted Submission(s): 2049
Problem 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
题目解析:并查集,该题的难点主要是对线段相交的判断
代码如下:
# include<stdio.h>
# include<string.h>
# include<math.h>
int f[1005];
int n;
int find(int x)
{
return x == f[x] ? x : f[x]=find(f[x]);
}
struct point{
double x,y;
};
struct node{
point s,e;
}a[1005];
double product(point &a, point &b, point &c){
double x1,y1,x2,y2;
x1 = a.x - c.x; y1 = a.y - c.y;
x2 = b.x - c.x; y2 = b.y - c.y;
return (x1*y2 - x2*y1);
}
bool intersect(node &a, node &b){ //判断线段是不是相交
if (
product(a.s,a.e,b.s)*product(a.s,a.e,b.e)<=0 &&
product(b.s,b.e,a.s)*product(b.s,b.e,a.e)<=0 ) return 1;
return 0;
}
int main(){
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n+10;i++)
f[i]=i;
int k1=0,k2=0;
while(n--)
{
getchar();
char cc;
scanf("%c",&cc);
if(cc=='P')
{
k1++;
scanf("%lf %lf %lf %lf",&a[k1].s.x,&a[k1].s.y,&a[k1].e.x,&a[k1].e.y);
for(int i=1;i<k1;i++)
{
if(intersect(a[k1],a[i])) //如果相交
{
int c3=find(i); //连接
int c4=find(k1);
if(c3!=c4)
f[c3]=c4;
}
}
}
else if(cc=='Q'){
int m;
scanf("%d",&m);
int count=0;
int c1=find(m);
for(int i=1;i<=k1;i++)
{
int c2=find(i);
if(c2==c1)
count++;
}
printf("%d\n",count);
}
}
if(t)
printf("\n");
}
return 0;
}