码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1558 Segment set(并查集之三)

时间:2015-11-04 17:14:52      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

问题描述:

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.
 


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

问题思路:

P命令插入一条线段。

Q命令查询线段K所在线段集合的线段数目。

套用了判断两条线段是否相交的模板。

 

代码:

#include<stdio.h>
#include<algorithm>
using namespace std;
int pre[1007];
struct point
{
    double x;
    double y;
};
double mult(point a,point b,point c)
{
    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
}
bool check(point aa,point bb,point cc,point dd)
{
    if(max(aa.x,bb.x)<min(cc.x,dd.x))
        return false;
    if(max(aa.y,bb.y)<min(cc.y,dd.y))
        return false;
    if (max(cc.x,dd.x)<min(aa.x,bb.x))
        return false;
    if(max(cc.y,dd.y)<min(aa.y,bb.y))
        return false;
    if(mult(cc,bb,aa)*mult(bb,dd,aa)<0)
        return false;
    if(mult(aa,dd,cc)*mult(dd,bb,cc)<0)
        return false;
    return true;
}
int find(int x)
{
    int r=x;
    while(r!=pre[r])
        r=pre[r];
    int i=x,j;
    while(i!=r)
    {
        j=pre[i];
        pre[i]=r;
        i=j;
    }
    return r;
}
void mix(int x,int y)
{
    int fx=find(x);
    int fy=find(y);
    if(fx!=fy)
        pre[fy]=fx;
}
void compress(int x)
{
    int r=x;
    while(r!=pre[r])
        r=pre[r];
    pre[x]=r;
}
int main()
{
    int n,T,count_p;
    char c;
    struct point p1[1007];
    struct point p2[1007];
    while(scanf("%d",&T)!=EOF)
    {
        while(T--)
        {
            scanf("%d",&n);
            getchar();
            count_p=0;
            for(int i=1;i<=n;i++)
                pre[i]=i;
            for(int i=1;i<=n;i++)
            {
                c=getchar();
                if(c==P)
                {
                    count_p++;
                    scanf("%lf%lf%lf%lf",&p1[count_p].x,&p1[count_p].y,&p2[count_p].x,&p2[count_p].y);
                    getchar();
                    for(int j=1;j<count_p;j++)
                        if(check(p1[count_p],p2[count_p],p1[j],p2[j]))
                            mix(count_p,j);
                }
                else{
                    int x;
                    int count=0;
                    scanf("%d",&x);
                    getchar();
                    for(int i=1;i<=n;i++)
                        compress(i);
                    int root=find(x);
                    for(int i=1;i<=n;i++)
                        if(pre[i]==root)
                            count++;
                    printf("%d\n",count);
                }
            }
            if(T!=0)
                printf("\n");
        }
    }
    return 0;
}

 

HDU 1558 Segment set(并查集之三)

标签:

原文地址:http://www.cnblogs.com/burning-flame/p/4936367.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!