poj-1556-The Doors-dij+线段相交

计算几何:求两条线段是否相交。

求两条线段是否相交只需要求两条线段的两个短点是否都在另外一条线段的两侧即可。

图论:dij求最短路

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<math.h>
using namespace std;
#define maxn 200000
#define eps 0.00001
#define zero(x) ((fabs(x)<eps)?0:x)
#define maxx 9999999
struct point
{
    double x;
    double y;
} p[20000],pp;
struct line
{
    point a;
    point b;
} l[20000];
int lnum;
double xmult(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
bool opposite_side(point u1,point u2,point v1,point v2)
{
    return xmult(v1,u1,u2)*xmult(v2,u1,u2)<-eps;
}
bool jiao(point u1,point u2,point v1,point v2)
{
    return opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);
}
double dis(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct list
{
    int u;
    int v;
    double w;
    int next;
} edge[maxn];
int head[maxn];
int num;
void add(int u,int v,double w)
{
    edge[num].u=u;
    edge[num].v=v;
    edge[num].w=w;
    edge[num].next=head[u];
    head[u]=num++;
}
int pan(point a,point b)
{
    for(int i=0;i<lnum;i++)
    {
        if(jiao(l[i].a,l[i].b,a,b))return 1;
    }
    return 0;
}
void dij(int y)
{
    double d[1100];
    int vis[1100];
    int i;
    for(i=0;i<=y;i++)d[i]=maxx;
    memset(vis,0,sizeof(vis));
    d[0]=0;
    while(1)
    {
        int ip;
        int minn=maxx;
        for(i=0;i<=y;i++)
        {
            if(vis[i])continue;
            if(d[i]<minn){minn=d[i];ip=i;}
        }
        if(minn==maxx)break;
        vis[ip]=1;
        for(i=head[ip];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(vis[v])continue;
            d[v]=min(d[v],d[ip]+edge[i].w);
        }
    }
    printf("%.2f\n",d[y]);
}
int main()
{
    int n,i,j,k;
    double x;
    while(~scanf("%d",&n))
    {
        memset(head,-1,sizeof(head));
        if(n==-1)break;
        p[0].x=0;
        p[0].y=5;
        num=0;
        lnum=0;
        for(i=1; i<=n; i++)
        {
            cin>>x;
            pp.x=x;
            pp.y=0;
            l[lnum].a=pp;
            for(k=1; k<=4; k++)
            {
                cin>>p[(i-1)*4+k].y;
                p[(i-1)*4+k].x=x;
                for(j=0; j<=(i-1)*4; j++)
                {
                    if(!pan(p[j],p[(i-1)*4+k]))add(j,(i-1)*4+k,dis(p[j],p[(i-1)*4+k]));
                }
            }
            pp.y=p[i*4-3].y;
            l[lnum++].b=pp;
            pp.y=p[i*4-2].y;
            l[lnum].a=pp;
            pp.y=p[i*4-1].y;
            l[lnum++].b=pp;
            pp.y=p[i*4].y;
            l[lnum].a=pp;
            pp.y=10;
            l[lnum++].b=pp;
        }
        p[n*4+1].x=10;
        p[n*4+1].y=5;
        for(j=0; j<=n*4; j++)
        {
            if(!pan(p[j],p[n*4+1]))add(j,n*4+1,dis(p[j],p[n*4+1]));
        }
        dij(n*4+1);
    }
    return 0;
}


你可能感兴趣的:(poj-1556-The Doors-dij+线段相交)