hdu1558 (Computational Geometry + concurrent search set)

Keywords: Programming PHP iOS

http://acm.hdu.edu.cn/showproblem.php?pid=1558

Question meaning: n kinds of operations, p is adding line segment, q is asking, asking how many line segments there are in the online intersection set of the line segments of the current serial number, including themselves

First

A template for calculating geometry to determine whether two line segments intersect:

struct Point{
    double x, y;
    Point(){};
    Point(double _x,double _y){
        x = _x;
        y = _y;
    }
};
struct Line{
    Point a,b;
    Line(){};
    Line(Point _a,Point _b){
        a = _a;
        b = _b;
    }
};
bool judge(Point a,Point b,Point c,Point d)
{
       if(!(min(a.x,b.x)<=max(c.x,d.x) && min(c.y,d.y)<=max(a.y,b.y)&&min(c.x,d.x)<=max(a.x,b.x) && min(a.y,b.y)<=max(c.y,d.y)))
        return false;

       double u,v,w,z;//Record two vectors separately
       u=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);
       v=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y);
       w=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y);
       z=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);
       return (u*v<=0.00000001 && w*z<=0.00000001);
}

Open a search array fa, and then an array rank to record the number of segments in the intersection line set where the current point is located

Every time a point is updated, it will be judged once in a cycle to determine the relationship between the point and the previous point, and then merge

When asking, you can directly print the number of line segments in the set where the parent node of the point is located,

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
const double INF = 99999999;
const int mod = 100003;
struct Point{
    double x, y;
    Point(){};
    Point(double _x,double _y){
        x = _x;
        y = _y;
    }
};
struct Line{
    Point a,b;
    Line(){};
    Line(Point _a,Point _b){
        a = _a;
        b = _b;
    }
};
int n, cnt, fa[N], Rank[N];
vector<int> query;
Line line[N];
int Find(int k)
{
    if(k != fa[k])
        fa[k] = Find(fa[k]);
    return fa[k];
}
void Merge(int x,int y)
{
    int dx = Find(x);
    int dy = Find(y);
    if(dx != dy){
        fa[dy] = dx;
        Rank[dx] += Rank[dy];
        //Rand[dy] = Rand[dx]; this sentence should not have, and the final output is find(num), so no additional addition is needed or it will be aggravated
    }
}
void init()
{
    for(int i = 0;i < N;i ++){
        fa[i] = i;
        Rank[i] = 1;
    }
}
bool judge(Point a,Point b,Point c,Point d)
{
       if(!(min(a.x,b.x)<=max(c.x,d.x) && min(c.y,d.y)<=max(a.y,b.y)&&min(c.x,d.x)<=max(a.x,b.x) && min(a.y,b.y)<=max(c.y,d.y)))
        return false;

       double u,v,w,z;//Record two vectors separately
       u=(c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y);
       v=(d.x-a.x)*(b.y-a.y)-(b.x-a.x)*(d.y-a.y);
       w=(a.x-c.x)*(d.y-c.y)-(d.x-c.x)*(a.y-c.y);
       z=(b.x-c.x)*(d.y-c.y)-(d.x-c.x)*(b.y-c.y);
       return (u*v<=0.00000001 && w*z<=0.00000001);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while(T --){
        init();
        cin >> n;
        double xx1,yy1,xx2,yy2;
        char c;
        int num;
        cnt = 0;
        for(int i = 1;i <= n;i ++){
            cin >> c;
            if(c == 'P'){
                cin >> xx1 >> yy1 >> xx2 >> yy2;
                line[++cnt] = Line(Point(xx1,yy1),Point(xx2,yy2));
                //Judge the relationship between the current point and the previous point
                for(int i = 1;i < cnt;i ++){
                    if(judge(line[i].a,line[i].b,line[cnt].a,line[cnt].b))
                        Merge(i,cnt);
                }
            }else{
                cin >> num;
                cout << Rank[Find(num)] << '\n';
            }
        }
        if(T)
            cout << '\n';
    }
    return 0;
}

 

Posted by mobiuz on Fri, 13 Dec 2019 13:06:00 -0800