hdu1558计算几何加并查集

不知道杭电题目分类是咋分的,这题我是在“匹配”里找到的,太假了。这明显是计算几何加并查集嘛。当然,并查集部分很简单,主要就是计算几何了,打了两个小时,我了个去,计算几何功底还是不行啊。。。

/*
 * hdu1558/win.cpp
 * Created on: 2012-8-16
 * Author    : ben
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
const int MAXN = 1005;

#define zero(x) (((x)>0?(x):-(x))<eps)
const double eps = 1e-8;
typedef double typec;
typedef struct MyPoint {
    typec x;
    typec y;
}MyPoint;
typedef struct MyLine {
    MyPoint a;
    MyPoint b;
}MyLine;
inline double xmult(MyPoint p1, MyPoint p2, MyPoint p0) {
    return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
int dots_inline(MyPoint p1, MyPoint p2, MyPoint p3) {
    return !xmult(p1, p2, p3);
}
inline int same_side(MyPoint p1, MyPoint p2, MyLine l) {
    return xmult(l.a, p1, l.b) * xmult(l.a, p2, l.b) > eps;
}
inline typec xmult(typec x1, typec y1, typec x2, typec y2, typec x0, typec y0) {
    return (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0);
}
inline int dot_online_in(typec x, typec y, typec x1, typec y1, typec x2,
        typec y2) {
    if ((zero(x-x1) && zero(y-y1)) || (zero(x-x2) && zero(y-y2))) {
        return 2;
    }
    if (!zero(xmult(x,y,x1,y1,x2,y2))) {
        return -1;
    }
    if ((x1 - x) * (x2 - x) < eps && (y1 - y) * (y2 - y) < eps) {
        return 0;
    }
    return 1;
}
inline int dot_online_in(const MyPoint &p, const MyLine &l) {
    return dot_online_in(p.x, p.y, l.a.x, l.a.y, l.b.x, l.b.y);
}

//包括端点和部分重合
bool intersect_in(MyLine u, MyLine v) {
    if (!dots_inline(u.a, u.b, v.a) || !dots_inline(u.a, u.b, v.b))
        return !same_side(u.a, u.b, v) && !same_side(v.a, v.b, u);
    return dot_online_in(u.a, v) || dot_online_in(u.b, v)
            || dot_online_in(v.a, u) || dot_online_in(v.b, u);
}
int myset[MAXN], N;
MyLine lines[MAXN];
void initset() {
    for(int i = 0; i < MAXN; i++) {
        myset[i] = i;
    }
}
inline int myfind(int x) {
    return myset[x];
}
void mymerge(int a, int b) {
    if(a > b) {
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;
    }
    for(int k = 0; k <= N; k++) {
        if(myset[k] == b) {
            myset[k] = a;
        }
    }
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("data.in", "r", stdin);
#endif
    int T, K, t;
    char c;
    scanf("%d", &T);
    while(T--) {
        initset();
        scanf("%d", &K);
        N = 0;
        while(K--) {
            scanf(" %c", &c);
            if(c == 'P') {
                scanf("%lf%lf%lf%lf", &lines[N].a.x, &lines[N].a.y, &lines[N].b.x, &lines[N].b.y);
                for(int i = 0; i < N; i++) {
                    if(intersect_in(lines[i], lines[N])) {
                        mymerge(myfind(i), myfind(N));
                    }
                }
                N++;
            }else if(c == 'Q'){
                scanf("%d", &t);
                t = myfind(t - 1);
                int ans = 0;
                for(int i = 0; i < N; i++) {
                    if(myset[i] == t) {
                        ans++;
                    }
                }
                printf("%d\n", ans);
            }
        }
        if(T > 0) {
            putchar('\n');
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/moonbay/p/2645211.html