【题意】给你一些线段,求出哪些线段是相连的,哪些是不相连的。相连包括间接相连,即这两条线段本身不直接相连,而是通过其它线段的连接而间接相连。

【解题方法】

解决这道题目的关键要解决两个问题:1.判断两条线段是否直接相连,即它们相交与否,这是一个几何问题;2.如果某两条线段不相交,那么它们是否通过其它线段的连接而间接相连。这个地方方法可以用并查集,也可以用Floyd-Warshall算法,我选择后者!

【AC 代码】

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps=1e-10;
const int maxn=20;
const int maxm=10010;
//考虑有误差的加法运算
double add(double a,double b)
{
    if(fabs(a+b)<eps*(fabs(a)+fabs(b))) return 0;
    return a+b;
}
//二维向量结构体
struct P{
    double x,y;
    P(){}
    P(double x,double y):x(x),y(y){}
    P operator +(P p){
        return P(add(x,p.x),add(y,p.y));
    }
    P operator -(P p){
        return P(add(x,-p.x),add(y,-p.y));
    }
    P operator *(double d){
        return P(x*d,y*d);
    }
    double dot(P p){ //内积
        return add(x*p.x,y*p.y);
    }
    double det(P p){//差集
        return add(x*p.y,-y*p.x);
    }
};
//判断点q是否在线段p1-p2上
bool on_seg(P p1,P p2,P q){
    return (p1-q).det(p2-q)==0&&(p1-q).dot(p2-q)<=0;
}
//计算p1-p2与直线q1-q2的交点
P intersection(P p1,P p2,P q1, P q2){
    return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}
//输入
int n;
P p[maxn],q[maxn];
int m;
int a[maxm],b[maxm];
bool g[maxn][maxn]; //相连关系图
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        for(int i=0; i<n; i++) scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
        m=0;
        int x,y;
        while(scanf("%d%d",&x,&y)){
            if(x==0&&y==0) break;
            a[m]=x,b[m]=y;
            m++;
        }
        for(int i=0; i<n; i++){
            g[i][i]=true;
            for(int j=0; j<i; j++){
                //判断木棍i和木棍j是否有公共交点
                if((p[i]-q[i]).det(p[j]-q[j])==0){
                    //平行时,检查端点
                    g[i][j]=g[j][i]=on_seg(p[i],q[i],p[j])||
                                    on_seg(p[i],q[i],q[j])||
                                    on_seg(p[j],q[j],p[i])||
                                    on_seg(p[j],q[j],q[i]);
                }else{
                    //非平行时
                    P r=intersection(p[i],q[i],p[j],q[j]);
                    g[i][j]=g[j][i]=on_seg(p[i],q[i],r)&&on_seg(p[j],q[j],r);
                }
            }
        }
        //通过Floyd算法判断任意两点是否相连
        for(int k=0; k<n; k++){
            for(int i=0; i<n; i++){
                for(int j=0; j<n; j++){
                    g[i][j]|=g[i][k]&&g[k][j];
                }
            }
        }
        for(int i=0; i<m; i++){
            puts(g[a[i]-1][b[i]-1]?"CONNECTED":"NOT CONNECTED");
        }
    }
}