Segment set
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2411 Accepted Submission(s): 932
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
思路:对所有线段两两判断是否相交,然后并查集合并区间即可。
View Code
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAX = 1005; 9 10 struct point 11 { 12 double x,y; 13 }; 14 15 struct node 16 { 17 point st,ed; 18 }; 19 20 struct Fater 21 { 22 int fat,size; 23 }; 24 25 Fater father[MAX]; 26 node seg[MAX]; 27 int N; 28 29 int find(int x) 30 { 31 if(x != father[x].fat) 32 father[x].fat = find(father[x].fat); 33 return father[x].fat; 34 } 35 36 double mul(point p2,point p1,point p0) 37 { 38 return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y)); 39 } 40 41 bool intersect(node s1,node s2) 42 { 43 if(min(s1.st.x,s1.ed.x)<=max(s2.st.x,s2.ed.x)&& 44 min(s2.st.x,s2.ed.x)<=max(s1.st.x,s1.ed.x)&& 45 min(s1.st.y,s1.ed.y)<=max(s2.st.y,s2.ed.y)&& 46 min(s2.st.y,s2.ed.y)<=max(s1.st.y,s1.ed.y)&& 47 mul(s2.st,s1.ed,s1.st)*mul(s1.ed,s2.ed,s1.st)>=0&& 48 mul(s1.ed,s2.ed,s2.st)*mul(s2.ed,s1.st,s2.st)>=0) 49 return true; 50 return false; 51 } 52 53 int main() 54 { 55 int Case; 56 scanf("%d",&Case); 57 for(int ca=1; ca<=Case; ca++) 58 { 59 int Q; 60 char oper; 61 int idx = 1,which; 62 for(int i=1; i<1001; i++) 63 { 64 father[i].fat = i; 65 father[i].size = 1; 66 } 67 scanf("%d",&Q); 68 getchar(); 69 while(Q--) 70 { 71 scanf("%c",&oper); 72 if(oper == 'P') 73 { 74 scanf("%lf%lf%lf%lf",&seg[idx].st.x,&seg[idx].st.y,&seg[idx].ed.x,&seg[idx].ed.y); 75 for(int i=idx-1; i>=1; i--) 76 { 77 if(intersect(seg[idx],seg[i])) 78 { 79 int t1 = find(i); 80 int t2 = find(idx); 81 if(t1 != t2) 82 { 83 father[t2].size += father[t1].size; 84 father[t1].fat = t2; 85 } 86 } 87 } 88 idx ++; 89 } 90 else 91 { 92 scanf("%d",&which); 93 int ans = find(which); 94 printf("%d\n",father[ans].size); 95 } 96 getchar(); 97 } 98 if(ca != Case) 99 printf("\n"); 100 } 101 return 0; 102 }


1927

被折叠的 条评论
为什么被折叠?



