您的位置:首页 > 其它

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

2016-04-17 18:41 302 查看
水神的栅栏
Time Limit: 1000 MSMemory 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");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息