hdu 1558

来源:互联网 发布:jade软件 编辑:程序博客网 时间:2024/06/13 04:15

计算几何,对我来说超级难。本来是练并查集的。这题的难点在于判断两条线段是否相交,利用向量的叉乘可以判断两个点是否在线段的两侧。点击打开链接这里有判断的推导。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000 + 5;struct point{    double x, y;};struct lines{    point a, b;} line[maxn];int pre[maxn];int num[maxn];int root(int x){    if(x != pre[x])        x = root(pre[x]);    return pre[x];}double xmult(point a, point b, point c){    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}bool corss(lines L1, lines L2){    point a = L1.a;    point b = L1.b;    point c = L2.a;    point d = L2.b;    double d1 = xmult(a, b, c);    double d2 = xmult(a, b, d);    double d3 = xmult(c, d, a);    double d4 = xmult(c, d, b);    //printf("%lf %lf-------  %lf  %lf\n", d1, d2, d3, d4);    //printf("%lf, %lf\n", d1 * d2, d3 *d4);    if(d1 * d2 < 0 && d3 * d4 < 0) return true;    else    {        if(d1 == 0 && c.x >= min(a.x, b.x) && c.x <= max(a.x, b.x)) return true;        if(d2 == 0 && d.x >= min(a.x, b.x) && d.x <= max(a.x, b.x)) return true;        if(d3 == 0 && a.x >= min(c.x, d.x) && a.x <= max(c.x, d.x)) return true;        if(d4 == 0 && b.x >= min(c.x, d.x) && b.x <= max(c.x, d.x)) return true;    }    //printf("no\n");    return false;}void merge_set(int f, int s){    int fx = root(f);    int fy = root(s);    //printf("yes\n");    pre[fy] = fx;    //printf("%d %d\n", fx, fy);    num[fx] = num[fx] + num[fy];}int main(){    int T, n;    char cmd[10];    scanf("%d", &T);    while(T--)    {        scanf("%d", &n);        for(int i = 0; i <= n; i++)            pre[i] = i;        for(int i = 0; i <= n; i++)            num[i] = 1;        int k = 0;        for(int kase = 1; kase <= n; kase++)        {            scanf("%s", cmd);            if(cmd[0] == 'P')            {                k++;                scanf("%lf%lf%lf%lf", &line[k].a.x, &line[k].a.y, &line[k].b.x, &line[k].b.y);                for(int i = 1; i < k; i++)                {                    //printf("%d %d\n", root(i), root(k));                    if(root(i) != root(k) && corss(line[i], line[k]))                    {                        //printf("yes %d\n ", i);                        merge_set(i, k);                    }                }            }            else            {                int t;                scanf("%d", &t);                //printf("%d\n", root(t));                printf("%d\n", num[root(t)]);            }        }        if(T) printf("\n");    }    return 0;}


原创粉丝点击