Jack Straws

Description

In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are connected by a path of touching straws. You will be given a list of the endpoints for some straws (as if they were dumped on a large piece of graph paper) and then will be asked if various pairs of straws are connected. Note that touching is connecting, but also two straws can be connected indirectly via other connected straws.

Input

Input consist multiple case,each case consists of multiple lines. The first line will be an integer n (1 < n < 13) giving the number of straws on the table. Each of the next n lines contain 4 positive integers,x1,y1,x2 and y2, giving the coordinates, (x1,y1),(x2,y2) of the endpoints of a single straw. All coordinates will be less than 100. (Note that the straws will be of varying lengths.) The first straw entered will be known as straw #1, the second as straw #2, and so on. The remaining lines of the current case(except for the final line) will each contain two positive integers, a and b, both between 1 and n, inclusive. You are to determine if straw a can be connected to straw b. When a = 0 = b, the current case is terminated.

When n=0,the input is terminated.

There will be no illegal input and there are no zero-length straws.

Output

You should generate a line of output for each
line containing a pair a and b, except the final line where a = 0 = b. The line
should say simply "CONNECTED", if straw a is connected to straw b, or
"NOT CONNECTED", if straw a is not connected to straw b. For our
purposes, a straw is considered connected to itself.

Sample
Input

7

1 6 3 3

4 6 4 9

4 5 6 7

1 4 3 5

3 5 5 5

5 2 6 3

5 4 7 2

1 4

1 6

3 3

6 7

2 3

1 3

0 0

2

0 2 0 0

0 0 0 1

1 1

2 2

1 2

0 0

0

Sample
Output

CONNECTED

NOT CONNECTED

CONNECTED

CONNECTED

NOT CONNECTED

CONNECTED

CONNECTED

CONNECTED

CONNECTED


判断直线相交利用徐本柱教授的跨立方法求解:

跨立的含义是:如果一条线段的一个端点在一条直线的一边,另一个端点在这条直线的另一端,我们就说这条线段跨立在这条直线上。显然,如果两条线段互相跨立,那它们一定是相交的。当然还有一些边值情况,也就是说有可能线段的端点在另一条线段所在的直线上。

线段相交满足且只需满足如下两个条件就可以了:
1 两条线段相互跨立;

2 一条线段的一个端点在另一条线段上。(这是针对边值情况而言的)
我们进一点来说明一下如何知道,一条线段是跨立在另一条线段上的。

如左图所示,线段向量 P1P2 是跨立在 P3P4 上的。我们取端点 P3 为虚线所示向量的起点,P1 和 P2 为终点,则向量组 P3P1、P3P4 和向量组 P3P2、P3P4 的叉积符号是相反的,因为由 P3P1 转向 P3P4 为顺时针,而由 P3P2 转向 P3P4 则为逆时针。同样的,也可以判断出 P3P4 是跨立在 P1P2 上的。这样我们就可以知道,两条线段是相交的。再看一看右图,按照跨立的方法,很容易知道,这两条线段是不相交的。

用跨立判断是否相交,相交用并查集连通处理。

最后读入棍子序号直接判断是不是双方都有一样的爸爸→_→。

下面给出代码:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define clr(x) memset(x,0,sizeof(x))
#define LL long long
using namespace std;
struct point
{
LL x,y;
point operator + (point b)
{
b.x=b.x+x;
b.y=b.y+y;
return b;
}
point operator - (point b)
{
b.x=x-b.x;
b.y=y-b.y;
return b;
}
point operator *(point b)
{
b.x=x*b.x;
b.y=y*b.y;
return b;
}
LL dot(point b)//点积
{
return x*b.x+y*b.y;
}
LL det(point b)//叉积
{
return x*b.y-y*b.x;
}
}u,v;
struct line
{
point pt1,pt2;
}a[];
int fa[];
void done(int n);
void Union(int a,int b);
int Find(int x);
bool infer(line a,line b);
LL onseg(point p,point p1,point p2);
int main()
{
int n;
while(scanf("%d",&n) && n!=)
{
done(n);
}
return ;
}
void done(int n)
{
clr(fa);
for(int i=;i<=n;i++)
fa[i]=i;
clr(a);
for(int i=;i<=n;i++)
{
scanf("%lld%lld%lld%lld",&a[i].pt1.x,&a[i].pt1.y,&a[i].pt2.x,&a[i].pt2.y);
if(a[i].pt1.x>a[i].pt2.x)
swap(a[i].pt1,a[i].pt2);
}
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(infer(a[i],a[j]))
{
Union(i,j);
}
int a,b;
while(scanf("%d%d",&a,&b) && a && b)
{
if(Find(a)==Find(b))
printf("CONNECTED\n");
else
printf("NOT CONNECTED\n");
}
return ;
}
void Union(int a,int b)
{
if(Find(a)!=Find(b))
fa[Find(a)]=Find(b);
return ; }
int Find(int x)
{
if(fa[x]==x)
return x;
return fa[x]=Find(fa[x]);
}
bool infer(line a,line b)//判断是否相交
{
if(a.pt2.x<b.pt1.x)//快速处理,若两条直线x部分或y部分不重叠,则肯定不相交。
return ;
if(a.pt1.y>a.pt2.y)
swap(a.pt1,a.pt2);
if(b.pt1.y>b.pt2.y)
swap(b.pt1,b.pt2);
if(a.pt2.y<b.pt1.y)
return ;
if((b.pt1-b.pt2).det(a.pt1-b.pt2)*(b.pt1-b.pt2).det(a.pt2-b.pt2)< && (a.pt2-a.pt1).det(b.pt1-a.pt1)*(a.pt2-a.pt1).det(b.pt2-a.pt1)<) return ;
//判断叉积符号是否相反,若相反则相交。
//判断叉积=0的情况。
if((b.pt1-b.pt2).det(a.pt1-b.pt2)== && onseg(a.pt1,b.pt1,b.pt2)) return ;
if((b.pt1-b.pt2).det(a.pt2-b.pt2)== && onseg(a.pt2,b.pt1,b.pt2)) return ;
if((a.pt2-a.pt1).det(b.pt1-a.pt1)== && onseg(b.pt1,a.pt1,a.pt2)) return ;
if((a.pt2-a.pt1).det(b.pt2-a.pt1)== && onseg(b.pt2,a.pt1,a.pt2)) return ;
//若均不符合上述相交情况,则不相交。
return ;
}
LL onseg(point p,point p1,point p2)//判断p是否在p1,p2上。
{
if(p1.x>p2.x)
swap(p1,p2);
if(p.x<p1.x || p.x>p2.x) return ;
if(p1.y>p2.y)
swap(p1,p2);
if(p.y<p1.y || p.y>p2.y) return ;
return ;
}

poj 1127(直线相交+并查集)的更多相关文章

  1. poj 1127:Jack Straws(判断两线段相交 + 并查集)

    Jack Straws Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2911   Accepted: 1322 Descr ...

  2. [poj 1127]Jack Straws[线段相交][并查集]

    题意: 给出一系列线段,判断某两个线段是否连通. 思路: 根据线段相交情况建立并查集, 在同一并查集中则连通. (第一反应是强连通分量...实际上只要判断共存即可, 具体的方向啊是没有关系的..) 并 ...

  3. poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

    Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...

  4. TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集

    题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> ...

  5. hdu 1558 线段相交+并查集

    题意:要求相交的线段都要塞进同一个集合里 sol:并查集+判断线段相交即可.n很小所以n^2就可以水过 #include <iostream> #include <cmath> ...

  6. 判断线段相交(hdu1558 Segment set 线段相交+并查集)

    先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...

  7. hdu 1558 (线段相交+并查集) Segment set

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1558 题意是在坐标系中,当输入P(注意是大写,我当开始就wa成了小写)的时候输入一条线段的起点坐标和终点坐 ...

  8. poj 1733(带权并查集+离散化)

    题目链接:http://poj.org/problem?id=1733 思路:这题一看就想到要用并查集做了,不过一看数据这么大,感觉有点棘手,其实,我们仔细一想可以发现,我们需要记录的是出现过的节点到 ...

  9. poj 1182 食物链 (并查集)

    http://poj.org/problem?id=1182 关于并查集 很好的一道题,开始也看了一直没懂.这次是因为<挑战程序设计竞赛>书上有讲解看了几遍终于懂了.是一种很好的思路,跟网 ...

随机推荐

  1. 【游记】CTSC&APIO2017

    GDOI回来不到两天就前往北京参加CTSC和APIO. CTSC Day1 [考试] T1一道神奇的题,很快想到O(n2)做法,感觉ctsc题目难度应该很大,就没马上想着出正解(事实上这届CTSC偏水 ...

  2. Web Session 浅入浅出(山东数漫江湖)

    使用过几种Web App开发语言和框架,都会接触到Session的概念.即使是一个简单站点访问计数的功能,也常常使用Session来实现的.其他常用的领域还有购物车,登录用户等.但是,对Session ...

  3. bzoj 3450 DP

    首先我们设len[i]表示前i位,从第i位往前拓展,期望有多少个'o',那么比较容易的转移 len[i]=len[i-1]+1 s[i]='o' len[i]=0 s[i]='x' len[i]=(l ...

  4. setTimeOut和闭包

    掘金上看到一个setTimeout与循环闭包的思考题.拿过来看了下,一方面了解settimeout的运行机制,还有就是js闭包的特性.关于闭包,有如下解释: 在这里写一点我对闭包的理解.理解闭包的关键 ...

  5. 设计模式之Builder

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: Builder模式是一步一步创建一个复杂的对象,它允许用户可以只通过指定复杂对象. 将一个复杂 ...

  6. Java 中的方法内部类

    方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用. 一定要注意哦:由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 s ...

  7. perl模拟登录(1)

    use WWW::Mechanize; my $ua = WWW::Mechanize->new(); $ua->post('http://localhost/dvwa/DVWA-mast ...

  8. Python3 生成器

    生成器(genetor): 1>生成器只有在调用的时候才会生成相应的数据: 2>生成器只记录当前位置,有一个__next__()方法 3>yield可以实现单线程先的并发运算 1.列 ...

  9. 2017多校第9场 HDU 6166 Senior Pan 堆优化Dij

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意:给你一个有向图,然后给你k个点,求其中一个点到另一个点的距离的最小值. 解法:枚举二进制位 ...

  10. 2015多校第6场 HDU 5361 并查集,最短路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5361 题意:有n个点1-n, 每个点到相邻点的距离是1,然后每个点可以通过花费c[i]的钱从i点走到距 ...