您的位置:首页 > 其它

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

2014-03-24 17:03 274 查看
计算几何:求两条线段是否相交。

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

图论: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: