Segment set
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2644 Accepted Submission(s): 994
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并查集水题,这题要判线段相交。AC代码:#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <algorithm> #include <queue> #include <map> #include <cmath> #include <vector> #include <cstdlib> #define eps 1e-8 using namespace std; const int MAX=1005; int father[MAX],rank[MAX]; struct node { double x1,y1; double x2,y2; } line[1010]; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } double multiply1(node a,node b) { return (a.x1-a.x2)*(b.y1-a.y1)-(a.y1-a.y2)*(b.x1-a.x1); } double multiply2(node a,node b) { return (a.x1-a.x2)*(b.y2-a.y1)-(a.y1-a.y2)*(b.x2-a.x1); } bool inter(node a,node b) { if(max(a.x1,a.x2)>=min(b.x1,b.x2)&& max(b.x1,b.x2)>=min(a.x1,a.x2)&& max(a.y1,a.y2)>=min(b.y1,b.y2)&& max(b.y1,b.y2)>=min(a.y1,a.y2)&& multiply1(a,b)*multiply2(a,b)<=eps&& multiply1(b,a)*multiply2(b,a)<=eps) return true; else return false; } int Find_set(int n) { if(n!=father[n]) father[n]=Find_set(father[n]); return father[n]; } void Union(int a,int b) { a=Find_set(a); b=Find_set(b); if(a==b) return; father[b]=a; rank[a]+=rank[b]; } void init() { for(int i=0; i<MAX; i++) { father[i]=i; rank[i]=1; } } int main() { int t,n,m; char s[2]; scanf("%d",&t); while(t--) { init(); int cnt=1; scanf("%d",&n); while(n--) { scanf("%s",s); if(s[0]=='P') { scanf("%lf%lf%lf%lf",&line[cnt].x1,&line[cnt].y1,&line[cnt].x2,&line[cnt].y2); for(int i=1; i<cnt; i++) if(inter(line[i],line[cnt])) Union(i,cnt); cnt++; } else { scanf("%d",&m); int root=Find_set(m); printf("%d\n",rank[root]); } } if(t>0) printf("\n"); } return 0; }