poj 1127 Jack Straws(两线相交,并查集)

来源:互联网 发布:qt5 socket编程 编辑:程序博客网 时间:2024/04/28 12:29

题意:给你n条线段,编号从1到n,然后判断两个线段(输入以0,0结束)是否相连(间接相连也算相连)。


分析:

公式:p1*p2=(x1*x2,y1*y2)(内积),p1xp2=(x1*y2,x2*y1)(外积)

判断q是否在线段p1-p2上面,根据(p1-q)x(p2-q)=0来判断q是否在直线p1-p2上。利用内积(p1-q)*(p2-q)<0判断q是否在p1-p2之间。
p1-p2,q1-q2的交点:

(x,y)=p1+(p2-p1)*((q2-q1)x(q1-p1)/((q2-q1)x(p2-p1)));

并查集:由于数据太小,可以不用并查集,随便写写就好。





#include <iostream>#include<cstdio>#include<cmath>using namespace std;#define EPS 1e-10#define N 105struct point{    double a,b;    point(){}    point(double a,double b):a(a),b(b){}    point operator +(point p)    {        return point(p.a+a,p.b+b);    }    point operator -(point p)    {        return point(a-p.a,b-p.b);    }    point operator *(double p)    {        return point(a*p,b*p);    }    double dot(point p)//内积    {        return (p.a*a+p.b*b);    }    double det(point p)//外积    {        return (a*p.b-b*p.a);    }};point p1[N],p2[N];//判断q是否在线段p1-p2上bool on_str(point p1,point p2,point q){    return (abs((p1-q).det(p2-q))<EPS&&(p1-q).dot(p2-q)<EPS);}//求两直线交点point intersection(point p1,point p2,point q1,point q2){    return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));}bool judge(int i,int j){    if(abs((p1[i]-p2[i]).det(p1[j]-p2[j]))<EPS)    {         if(on_str(p1[i],p2[i],p1[j])||on_str(p1[i],p2[i],p2[j])||on_str(p1[j],p2[j],p1[i])||on_str(p1[j],p2[j],p2[i]))//判断是否有重合             return 1;        else             return 0;    }     point r=intersection(p1[i],p2[i],p1[j],p2[j]);    return on_str(p1[i],p2[i],r)&&on_str(p1[j],p2[j],r);}int myrank[N],par[N];void init(int n){    for(int i=0;i<n;i++)    {        myrank[i]=0;        par[i]=i;    }}int myfind(int x){    if(par[x]==x)        return x;    return par[x]=myfind(par[x]);}void unite(int x,int y){    x=myfind(x);    y=myfind(y);    if(x==y)return;    if(myrank[x]<myrank[y])    {        par[x]=y;    }    else    {        par[y]=x;        if(myrank[x]==myrank[y])            myrank[x]++;    }}bool same(int x,int y){    return myfind(x)==myfind(y);}int main(){    int n;    while(scanf("%d",&n)&&n)    {        init(n);        for(int i=0;i<n;i++){        scanf("%lf%lf%lf%lf",&p1[i].a,&p1[i].b,&p2[i].a,&p2[i].b);        }        for(int i=0;i<n;i++)        {            for(int j=0;j<i;j++)            {                if(judge(i,j))                {                    unite(i,j);                }            }        }        int a,b;        while(~scanf("%d%d",&a,&b)&&(!(a==0&&b==0)))        {            if(same(a-1,b-1))                printf("CONNECTED\n");            else                printf("NOT CONNECTED\n");        }    }    return 0;}


0 0
原创粉丝点击