C - Segment set

来源:互联网 发布:对你一直有空 知乎 编辑:程序博客网 时间:2024/06/02 01:20

C - Segment set
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit Status

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. 
 

Output

For each Q-command, output the answer. There is a blank line between test cases.
 

Sample Input

110P 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.00Q 5
 

Sample Output

12225


题意是给你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-10using 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;}


0 0
原创粉丝点击