并查集+上判断两条线段是否相交就可以了,仔细看数据集非常小,所以基本上可以不用考虑时间复杂度;
本题的难点主要是判断两条线段是否相交;特殊情况比较多,具体的见代码:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<algorithm>
using namespace std;
struct edge//边;
{
int x1,y1,x2,y2;
}e[15];
struct point//点;
{
int x,y;
};
int father[15];
int n;
int find(int x)//以下是最基础的并查集在这里就不多说了;
{
if(x==father[x]) return x;
else
return father[x]=find(father[x]);
}
void unite(int x,int y)
{
int xx=find(x);
int yy=find(y);
if(yy==xx) return;
else
father[yy]=xx;
return;
}
/*bool same(int x,int y)
{
return find_father(x)==find_father(y);
}*/
int judge(edge a,edge b)//这里是利用计算集合里面判断2个点是否在一条直线两边的方法,使用两次证明p1、p2在直线q1q2的两侧以及q1、q2在直线p1p2的两侧
{
point p1,p2,q1,q2,p,q;
p1.x=a.x1,p1.y=a.y1;
p2.x=a.x2,p2.y=a.y2;
q1.x=b.x1,q1.y=b.y1;
q2.x=b.x2,q2.y=b.y2;
p.x=p1.x-p2.x,p.y=p1.y-p2.y;
q.x=q1.x-q2.x,q.y=q1.y-q2.y;
int judgea,judgeb;
judgea=((q.x*(p1.y-q1.y))-(q.y*(p1.x-q1.x)))*((q.x*(p2.y-q1.y)-(q.y*(p2.x-q1.x))));
judgeb=((p.x*(q1.y-p1.y))-(p.y*(q1.x-p1.x)))*((p.x*(q2.y-p1.y)-(p.y*(q2.x-p1.x))));
if(judgea<=0&&judgeb<=0) return 1;//取等号就是考虑一条线段的端点可能在另一条线段上;
else
return 0;
}//但是只有这个是有特殊情况的考虑(1,1)-(2,2);(3,3)-(4,4)的情况,他们在同一条直线上但是不相交;所以有了judge2函数
int judge2(edge a,edge b)//这个函数主要是判断以这两条直线段为对角线的矩形是否有交集;显然如果没有交集显然来那个直线段不相交;
{
int minax=min(a.x1,a.x2);
int maxax=max(a.x1,a.x2);
int minay=min(a.y1,a.y2);
int maxay=max(a.y1,b.y2);
int minbx=min(b.x1,b.x2);
int maxbx=max(b.x1,b.x2);
int minby=min(b.y1,b.y2);
int maxby=max(b.y1,b.y2);
if(maxax<minbx||maxay<minby||maxbx<minax||maxby<minay) return 0;
else
return 1;
}
int main()
{
int inputa,inputb;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0;i<=n;i++) father[i]=i;//并查集的初始化;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&e[i].x1,&e[i].y1,&e[i].x2,&e[i].y2);
}
for(int i=1;i<=n;i++)//枚举两两直线段之间是否相交
{
for(int j=i+1;j<=n;j++)
{
if(judge(e[i],e[j])==1&&judge2(e[i],e[j])==1)//判断条件;
{
unite(i,j);//如果相交那么他们的根就相同,用并查集将他们合并;
}
}
}
while(scanf("%d%d",&inputa,&inputb)!=EOF)
{
if(inputa==0&&inputb==0) break;
if(find(inputa)==find(inputb)) printf("CONNECTED\n");
else
printf("NOT CONNECTED\n");
}
}
return 0;
}
顺便纪念一下。。计算几何第一题