POJ 1127 Jack Straws (计算几何)

【题目链接】 http://poj.org/problem?id=1127

【题目大意】

  在二维平面中,给出一些木棍的左右端点,当木棍相交或者间接相交时
  我们判断其连通,给出一些询问,问某两个木棍是否连通

【题解】

  我们首先记录直接相连的木棍,然后对图跑一遍floyd算法,就能预处理出所有答案。

【代码】

#include <cstdio>
#include <algorithm>
#include <cmath> 
#include <cstring>
using namespace std;
double EPS=1e-10;
double add(double a,double b){
    if(abs(a+b)<EPS*(abs(a)+abs(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));
}
const int MAX_N=12;
const int MAX_M=10000;
int n,m;
P p[MAX_N],q[MAX_N];
int a[MAX_M],b[MAX_M];
bool g[MAX_N][MAX_N];
void solve(){
	memset(g,0,sizeof(g));
    for(int i=0;i<n;i++){
        g[i][i]=1;
        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);
            }
        }
    }
    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");
    }
}
bool init(){
    scanf("%d",&n);
    if(n==0)return 0;
    for(int i=0;i<n;i++)scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
    int x,y; m=0;
    while(scanf("%d%d",&x,&y),x&&y){
        a[m]=x,b[m++]=y;
    }return 1;
}
int main(){
    while(init())solve();
    return 0;
}
原文地址:https://www.cnblogs.com/forever97/p/poj1127.html