hdu-1558 Segment set(几何计算+并查集)

hdu-1558 Segment set原题链接

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则查询某个线段所在的线段集合。(就是他相交了多少条线段)
这道题目很简单的就可以抽象成是并查集的问题,只要用一个正整数来表示线段的标志,然后判断这条新输入的线段和之前的所有线段有没有相交如果有则并入。

//  "你喜欢大海,我爱过你""你好骚哦"
//  main.cpp
//  HDU-1558
//
//  Created by Jccc on 2018/7/31.
//  Copyright © 2018年 zwu. All rights reserved.
//

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int ans[1010],f[1010];
struct Point
{
    double x,y;
}arr[1010],brr[1010];
void init()
{
    memset(arr,0,sizeof(arr));
    memset(brr,0,sizeof(brr));
    for(int i=1;i<=1010;i++)
    {
        f[i]=i;
        ans[i]=1;
    }
}
int Find(int x){
    if(x!=f[x]) f[x]=Find(f[x]);
    return f[x];
}
void Union(int x,int y)
{
    int u=Find(x),v=Find(y);
    if(u!=v){
        f[v]=u;
        ans[u]+=ans[v];
        ans[v]=0;
    }
}
double determinant(double v1, double v2, double v3, double v4)
{
    return (v1*v4-v2*v3);
}

bool intersect(Point aa, Point bb, Point cc, Point dd)
{
    double delta = determinant(bb.x-aa.x, cc.x-dd.x, bb.y-aa.y, cc.y-dd.y);
    if ( delta<=(1e-6) && delta>=-(1e-6) )
    {
        return false;
    }
    double namenda = determinant(cc.x-aa.x, cc.x-dd.x, cc.y-aa.y, cc.y-dd.y) / delta;
    if ( namenda>1 || namenda<0 )
    {
        return false;
    }
    double miu = determinant(bb.x-aa.x, cc.x-aa.x, bb.y-aa.y, cc.y-aa.y) / delta;
    if ( miu>1 || miu<0 )
    {
        return false;
    }
    return true;
}
int main() {
    int T;
    cin>>T;
    while (T--) {
            int n,num=1;
            cin>>n;
            init();
            while (n--) {
                char cr;
                double x1,y1,x2,y2;
                int Key;
                cin>>cr;
                if(cr=='Q') {
                    cin>>Key;
                    cout<<ans[Find(Key)]<<endl;
                }
                else{
                    cin>>x1>>y1>>x2>>y2;
                    arr[num].x=x1,arr[num].y=y1;
                    brr[num].x=x2,brr[num].y=y2;
                    for(int i=1;i<num;i++)
                    {
                        if(intersect(brr[i],arr[i],brr[num],arr[num]))
                            Union(i,num);
                    }
                    num++;
                }
            }
            if(T)cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/J1nAB1n9/article/details/81316372