题目链接:http://poj.org/problem?id=1127
Jack Straws
题目大意:给你n个线段,然后再给你m组数据,每组包含a,b两个线段,问你a,b是否CONNECTED ,(如果间接相交(即1交2,2交3,1虽然没有交3,但是也算相交),也算CONNECTED )。
解题思路:将相交于同一条直线的放入同一个并查集里面,然后查找即可。
#include <iostream>
#include <cstdio>
#include <algorithm>
#define eps 1e-10
using namespace std;
struct point
{
int x,y;
};
struct line
{
point a,b;
}l[15];
int pa[15];
bool inter(point a,point b,point c,point d)
{
if(min(a.x,b.x) > max(c.x,d.x) || min(a.y,b.y) > max(c.y,d.y) || min(c.x,d.x) > max(a.x,b.x) || min(c.y,d.y) > max(a.y,b.y))
return 0;
double h,i,j,k;
h = (b.x-a.x) * (c.y-a.y) - (b.y-a.y) * (c.x-a.x);
i = (b.x-a.x) * (d.y-a.y) - (b.y-a.y) * (d.x-a.x);
j = (d.x-c.x) * (a.y-c.y) - (d.y-c.y) * (a.x-c.x);
k = (d.x-c.x) * (b.y-c.y) - (d.y-c.y) * (b.x-c.x);
return h*i <= eps && j*k <= eps;
}
int findset(int x)
{
if(x == pa[x])
return pa[x];
else
return pa[x]=findset(pa[x]);
}
int main()
{
int n;
while(scanf("%d",&n),n)
{
int i,j,t1,t2,x,y;
for(i = 0; i <= n; i++)
pa[i] = i;
for(i = 1; i <= n; i++)
scanf("%d%d%d%d",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y);
for(i = 1; i <= n; i++)
{
for(j = i+1; j <= n; j++)
{
if(inter(l[i].a,l[i].b,l[j].a,l[j].b))
{
x = findset(i);
y = findset(j);
if(x != y)
pa[x] = y;
}
}
}
for(i = 1; i <= n; i++)
pa[i] = findset(i);
while(scanf("%d%d",&t1,&t2),t1&&t2)
{
if(pa[t1] == pa[t2])
printf("CONNECTED\n");
else
printf("NOT CONNECTED\n");
}
}
return 0;
}