挑战程序设计 &&计算几何&&POJ.1127 Jack Straws

来源:互联网 发布:php颜色代码 编辑:程序博客网 时间:2024/05/16 09:53

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

【解题方法】

解决这道题目的关键要解决两个问题: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");        }    }}


0 0