hrbust/哈理工oj 1507 水神的栅栏【计算几何+并查集】

水神的栅栏
Time Limit: 1000 MS Memory Limit: 65535 K
Total Submit: 41(16 users) Total Accepted: 18(15 users) Rating:  Special Judge: No
Description

     水神在赚了一笔钱之后,购买了一座庄园,做起了农场主,水神的农场都是靠栅栏围墙来分成很多部分并且围成外面的围墙的,但是最近一段时间,水神的庄园遭到了神兽的袭击,神兽撞破了很多处栅栏,这让水神非常苦恼,为了弄清楚自己的栅栏还有哪些地方时连着的,水神画了一张平面图,每一段栅栏在图上表示成一个线段,这些线段有的会相交,有的不会。

    水神需要知道两段栅栏是否可以连起来。

Input

有多组输入数据,每组数据:

第一行一个整数n表示水神农场的栅栏的个数(n<13)

接下来n行,每行四个整数x1,y1,x2,y2分别表示栅栏的两个端点坐标

然后下面若干行是对栅栏连接情况的询问,每行两个整数a,b表示水神想知道,栅栏a和栅栏b是否可以连起来。询问以0  0结束。

n=0时输入结束

Output

对于每次询问,如果栅栏a和b可以连起来,输出 CONNECTED,否则输出:NOT CONNECTED.

Sample Input

2

0 2 0 0

0 0 0 1

1 1

2 2

1 2

0 0

2

0 2 0 0

1 0 2 0

1 2

0 0

0

Sample Output

CONNECTED

CONNECTED

CONNECTED

NOT CONNECTED

Author
曹振海

解题思路:

用线段相交的快速排斥试验和跨立试验来判断两个栅栏是否相交。至于线段相交的详解,我这里提供链接:

1、http://blog.csdn.net/mengxiang000000/article/details/50587203源自我的博客

2、http://blog.csdn.net/qq_33184171/article/details/51114511源自蒟犇白羊大神的博客

如果两个栅栏形成的线段能够相交,辣么就说明这两个栅栏能够CONNECTED。否者就是NOT CONNECTED。

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
struct xianduan
{
    int x1,x2,y1,y2;
}a[15];
struct point
{
    int x,y;
}b[10];
int f[155];
int find(int x)
{
    return f[x] == x ? x : (f[x] = find(f[x]));
}
void merge(int a,int b)
{
    int A,B;
    A=find(a);
    B=find(b);
    if(A!=B)
    f[B]=A;
}
double multi(point p1,point p2,point p0)
{
    return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}

bool IsIntersected(point s1,point e1,point s2,point e2)//两个线段相交
{
    return(max(s1.x,e1.x)>=min(s2.x,e2.x))&&
           (max(s2.x,e2.x)>=min(s1.x,e1.x))&&
           (max(s1.y,e1.y)>=min(s2.y,e2.y))&&
           (max(s2.y,e2.y)>=min(s1.y,e1.y))&&
           (multi(s1,s2,e1)*multi(s1,e1,e2)>=0)&&
           (multi(s2,s1,e2)*multi(s2,e2,e1)>=0);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        if(n==0)break;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
        }
        for(int i=1;i<=n;i++)
        {
            f[i]=i;
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                b[0].x=a[i].x1,b[0].y=a[i].y1;
                b[1].x=a[i].x2,b[1].y=a[i].y2;
                b[2].x=a[j].x1,b[2].y=a[j].y1;
                b[3].x=a[j].x2,b[3].y=a[j].y2;
                if(IsIntersected(b[0],b[1],b[2],b[3]))
                {
                    merge(i,j);
                }
            }
        }
        while(1)
        {
            int xx,yy;
            scanf("%d%d",&xx,&yy);
            xx--;yy--;
            if(xx==-1&&yy==-1)break;
            if(find(xx)==find(yy))
            {
                printf("CONNECTED\n");
            }
            else printf("NOT CONNECTED\n");
        }
    }
}





你可能感兴趣的:(hrbust,哈理工oj,1507,1507)