Topic:
| Segment Set |
| Time limit:3000/1000 MS (java/others) Memory limit:32768/32768 K (java/others) |
| Total submission (s): 177 Accepted Submission (s): 82 |
|
Problem Descriptiona segment and all segments which is 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.
|
Inputin The first line there is a integer t-the number of test case. For all test case on first line there is an integer n (n<=1000)-the number of commands.
There is different commands described in different format shown below:
P x1 Y1 x2 y2-paint A segment whose coordinates of the The and 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 and 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 Input110P 1.00 1.00 4.00 2.00P 1.00-2.00 8.00 4.00Q 1P 2.00 3.00 3.00 1.00Q 1Q 3P 1.00 4.00 8.00 2.00Q 2P 3.00 3.00 6.00-2.00 Q 5 |
Sample Output12225 |
| Authorll |
| Sourcehdu 2006-12 Programming Contest |
| Recommendll |
Main topic:
The concept of "line set" is explained here: There are a,b,c three line segments. If A and b intersect, b intersects with C (line A and segment C may not intersect directly). So this time a,b,c still belong to the same segment set. When you enter the sample, the P represents the addition of a new edge, followed by an edge
The horizontal ordinate of the starting point and the end point
Topic Analysis:
Calculates the geometry + and checks the set. In fact, the concept of "intersect" in the calculation set is used to determine whether two segments intersect. The general idea is that when a segment is added, if the two segments intersect, the two segments are merged into the same set of segments. And then, in the Q, query for a certain bar
The number of segments in the Segment collection where the segment is located.
The code is as follows:
/* * c.cpp * * Created on:2015 February 28 * author:administrator * * #include <iostream> #include <cstdio> #inc Lude <algorithm> #include <cmath>using namespace std;const int maxn = 1001;int father[maxn];//for saving parent-child relationship int r[ maxn];//is used to hold a node as the root of the weight. (This can be understood as the number of points in a set of segments). For example, R[a] represents the weight of the collection with a as the root node, the number of counter;//of the current edge/** * Look for the root node of the collection where a node is located */int find (int a) {if (A = = Father[a]) {return A;} return Father[a] = find (Father[a]);} /** * Merge the set where the A node is located and the set where Node B is located */void join (int a, int b) {int fa = find (a);//Find Node A at the root of the collection, int fb = find (b);//Find the root node of the collection where Node B is located if (f A! = FB) {//If the root node of a collection is not the same as the root node of the collection where B is located father[fa] = fb;//merges the two collections. The operating room performed here will point a at the root node of the set where the root node of the set is located FA points to the roots of the collection FBR[FB] + = r[fa];// Add the weight of the node FA to the node FB/** * Set the weight of the node FA to 0. Why do you do this? * Mainly in order to avoid the repetition of weights and additions. This is determined by the execution of the function that follows Addedge (). * Each time there is a new edge, Addedge () iterates through all the edges in the edge collection to see if it intersects with the new edge and, if it intersects, executes and operates the join (). At this point the weight of one whip moves to the other side. * For example, there are three sides with a serial number of three-way. They add a collection of lanes in turn. Their weights are 1,1,1. If the three edges belong to the same set, the weight of this set should be 1+1+1=3. * * When adding edge 2, if the Edge 1 and Edge 2 intersect, then the weight of the Edge 2 is 2 * If not the weight of the node 1 is 0, then on the side MarchSide 2, side 1 are intersect case, * then after the merger operation, the weight of the obtained and check set is 1+2+1=4, which is obviously incorrect */r[fa] = 0;}} struct Point {//points double x;//horizontal axis double y;//ordinate};struct edge {//Edge point start;//start points end;//end point}edges[maxn];//Edge Collection 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));} A (x1,y1), B (x2,y2)//x1*y2-x2*y1/** * Determines whether two segments intersect */int intersect (Edge u, Edge v) {return (max (u.start.x, u.end.x) >= m In (V.start.x, v.end.x)) && whether the rightmost point in the//u is to the right of the leftmost point of V (Max (v.start.x, v.end.x) >= min (u.start.x, u.end.x) & & whether the rightmost point in the//v is on the right side of the U leftmost point//Determines whether the two segments may intersect at the horizontal level (max (U.START.Y, U.end.y) >= min (V.start.y, v.end.y)) &&// Whether the topmost point in U is at the top of the point at the bottom of the V (Max (V.start.y, V.end.y) >= min (U.start.y, u.end.y)) && whether the topmost point in the//v is at the top of the U-bottom point// Determine if the two segments may intersect at a vertical level (multiply (V.start, u.end, U.start) * Multiply (u.end, v.end, U.start) >= 0) &&//Judge V.start, Whether the v.end is distributed on both sides of the u.end (or on the line) (Multiply (U.start, v.end, V.start) * Multiply (v.end, u.end, V.start) >= 0);//Judging U.start, Whether the u.end is distributed inV.start side (or line)}/** * Add edge Operation */void Addedge () {int i;for (i = 1; i < counter; ++i) {//The newly added edge is compared to all edges in the current edge collection if (Intersect (EDG Es[i],edges[counter]) = = true) {//Determine if they intersect join (i,counter);//If the intersection performs a merge operation}}}/** * Initialize */void init () {int i;for (i = 1; i < MAXN; ++i) {//Traverse all nodes. The index starts at 1 and does not start at 0. There will be some problems. Seriously think about why father[i] = i;//all nodes of the Father node start by default is its own r[i] = 1;//all nodes The default weight is 1}}int main () { int t;scanf ("%d", &t); int cas = 0;//is primarily used for test cases where a blank line is printed after (t--) {if (cas! = 0) {// It is important to note the same statement. Some of the topics in all the blank line can be AC, and some must be the last one can not play blank line printf ("\ n");} Cas++;counter = 1;//number of edges starting from 1 init (), int m;scanf ("%d", &m), String str;int i;for (i = 1; I <= m; ++i) {//need to be aware of this form of input sample C In >> str;if (str[0] = = ' P ') {scanf ("%lf%lf%lf%lf", &edges[counter].start.x,&edges[counter].start.y, &EDGES[COUNTER].END.X,&EDGES[COUNTER].END.Y); Addedge (); counter++;} Else{int index;scanf ("%d", &index);p rintf ("%d\n", R[find (Index)]);}} printf ("\ n");} return 0;}
(Hdu step 5.1.3) Segment set (the number of segments in the collection of segments that intersect a segment)