最短路+叉积 poj1556

题目链接:The Doors - POJ 1556 - Virtual Judge  https://vjudge.net/problem/POJ-1556

题意是叫我们计算从(0,5)到(10,5)的最短路,中间会给出n道墙,每道墙会有两扇门可以通过,第一行是数字n,接下来n行,每行有x,y1,y2,y3,y4,表示横坐标为x的门上的四个点坐标。

在这里主要是把图建出来,我的做法是先把所有点和墙存下来,然后枚举每两点,这两点要满足横坐标不同,并且两点的连线不经过在两点的横坐标之间的墙,假设我们有两个点p1,p2,有一道墙的横坐标是x,那么只要(p1.x-x)*(p2.x-x)<0,这两个点就在墙的左右两边,然后再判断和墙有没有交点,这个用叉积计算墙的两点是不是在我们两点连线的两边,把图建完就用floyd或者dijkstra计算一下最短路就可以了,可能讲的不是很清楚,看一下代码:

struct node{
    double x,y;
}p[1005];  //存点
struct ss{
    node a,b;
}wall[1005];//存墙

我写的有点麻烦:

     p[0].x=0,p[0].y=5;
        p[1].x=10,p[1].y=5;//起点和终点分别存进去
        cnt1=2;    //点的数量
        cnt2=0;    //墙的数量
        for(int i=0;i<n;i++)
        {
            double x,y;
            cin>>x;
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;  //第一个点
            wall[cnt2].a=p[cnt1];    //第一道墙
            wall[cnt2].b.x=x;
            wall[cnt2].b.y=0;
            cnt1++;
            cnt2++;
            
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;  //第二个点
            cnt1++;
            
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;  //第三个点
            
            wall[cnt2].a=p[cnt1];
            wall[cnt2].b=p[cnt1-1];  //第二道墙
            cnt1++;
            cnt2++;
            
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;  //第四个点和第三道墙,好麻烦
            wall[cnt2].a=p[cnt1];
            wall[cnt2].b.x=x;
            wall[cnt2].b.y=10;
            cnt1++;
            cnt2++;
        }

判断两点之间有没有墙

bool jug(int a,int b)
{
    for(int i=0;i<cnt2;i++)
    {
        double x=wall[i].a.x;
        double k=(p[a].x-x)*(p[b].x-x);    //判断墙在两点之间
        double k1=cross(p[a],p[b],wall[i].a);//判断墙的两点是否在连点的直线两边
        double k2=cross(p[a],p[b],wall[i].b);
        if(k<0&&k1*k2<eps)
        return true;
    }
    return false;
}

完整代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define eps 1e-10
#define inf 9999999
struct node{
    double x,y;
}p[1005];
struct ss{
    node a,b;
}wall[1005];
double map[1005][1005];
int n,m,k,t,cnt1,cnt2;
double dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cross(node a,node b,node c)
{
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool jug(int a,int b)
{
    for(int i=0;i<cnt2;i++)
    {
        double x=wall[i].a.x;
        double k=(p[a].x-x)*(p[b].x-x);
        double k1=cross(p[a],p[b],wall[i].a);
        double k2=cross(p[a],p[b],wall[i].b);
        if(k<0&&k1*k2<eps)
        return true;
    }
    return false;
}
void floyd()
{
    for(int k=0;k<cnt1;k++)
    {
        for(int i=0;i<cnt1;i++)
        {
            for(int j=0;j<cnt1;j++)
            {
                if(i!=j&&map[i][j]>map[i][k]+map[k][j])
                {
                    map[i][j]=map[i][k]+map[k][j];
                }
            }
        }
    }
}
int main()
{
    while(cin>>n)
    {
        if(n<0)
        break;
        p[0].x=0,p[0].y=5;
        p[1].x=10,p[1].y=5;
        cnt1=2;
        cnt2=0;
        for(int i=0;i<n;i++)
        {
            double x,y;
            cin>>x;
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;
            wall[cnt2].a=p[cnt1];
            wall[cnt2].b.x=x;
            wall[cnt2].b.y=0;
            cnt1++;
            cnt2++;
            
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;
            cnt1++;
            
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;
            
            wall[cnt2].a=p[cnt1];
            wall[cnt2].b=p[cnt1-1];
            cnt1++;
            cnt2++;
            
            cin>>y;
            p[cnt1].x=x,p[cnt1].y=y;
            wall[cnt2].a=p[cnt1];
            wall[cnt2].b.x=x;
            wall[cnt2].b.y=10;
            cnt1++;
            cnt2++;
        }
        for(int i=0;i<cnt1;i++)
        {
            for(int j=0;j<cnt1;j++)
            map[i][j]=inf;
        }
        for(int i=0;i<cnt1-1;i++)
        {
            for(int j=i+1;j<cnt1;j++)
            {
                if(i!=j&&p[i].x!=p[j].x&&!jug(i,j))
                {
                    map[i][j]=map[j][i]=dis(p[i],p[j]);
                }
            }
        }
        floyd();
        printf("%.2f
",map[0][1]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/6262369sss/p/9353493.html