poj 1556 The Doors(最短路+判断线段相交)

来源:互联网 发布:数据库物理模型主键 编辑:程序博客网 时间:2024/05/01 03:56

//以下为原blog搬迁过来的内容

【题目大意】:给出一个10*10的平面,对于平面上的每一个竖的截线都可能会有3面墙,题目会给出墙的端点坐标。然后要求求出(0,5)到(10,5)不穿过墙的最短路。

 

【解题思路】:枚举两个点,连接成线段,判断有木有墙与这题线段相交,如果没有的话,就可以前进。数据量比较小,求出所有直达的点后跑一次floyed就好了。

 

【代码】:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>#include <string>#include <cctype>#include <map>#include <iomanip>                   using namespace std;                   #define eps 1e-8#define pi acos(-1.0)#define inf 1<<30#define pb push_back#define lc(x) (x << 1)#define rc(x) (x << 1 | 1)#define lowbit(x) (x & (-x))#define ll long long#define INF 100000struct Point{    double x,y;    Point() {}    Point(double a,double b)    {        x=a,y=b;    }}point[100][100],point1[100];struct Line{    Point a,b;    Line() {}    Line(Point x,Point y)    {        a=x,b=y;    }}line[10000];double dis[100][100];int n,cnt1,cnt2,cnt;double p,q;inline int sig(double k){    return k < -eps ? -1 : k > eps;}inline double det(double x1, double y1, double x2, double y2){    return x1 * y2 - x2 * y1;}inline double xmult(Point o, Point a, Point b){    return det(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y);}inline int intersect1(Point a, Point b, Point c, Point d){    double s1, s2, s3, s4;    int d1 = sig(s1 = xmult(a, b, c));    int d2 = sig(s2 = xmult(a, b, d));    int d3 = sig(s3 = xmult(c, d, a));    int d4 = sig(s4 = xmult(c, d, b));    if ((d1^d2) == -2 && (d3^d4) == -2)    {        return 1;    }    return 0;}inline int intersect(Line u, Line v){    return intersect1(u.a, u.b, v.a, v.b);}inline double getDist(Point a, Point b){    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}int main(){    while (~scanf("%d",&n))    {        if (n==-1) break;        point1[0]=Point(0,5);        cnt1=1;        cnt2=0;        for (int i=0; i<=n-1; i++)        {            scanf("%lf",&p);            cnt=0;            point[i][cnt]=Point(p,0);            cnt++;            for (int j=1; j<=4; j++)            {                scanf("%lf",&q);                point[i][cnt]=Point(p,q);                point1[cnt1]=Point(p,q);                cnt1++;                cnt++;            }            point[i][cnt]=Point(p,10);            cnt++;            line[cnt2]=Line(point[i][0],point[i][1]);            cnt2++;            line[cnt2]=Line(point[i][2],point[i][3]);            cnt2++;            line[cnt2]=Line(point[i][4],point[i][5]);            cnt2++;        }        /* for (int i=0; i<cnt2; i++)        {            cout << line[i].a.x << " " << line[i].a.y << " " << line[i].b.x<< " " <<line[i].b.y<<endl;        }*/        point1[cnt1]=Point(10,5);        cnt1++;        for (int i=0; i<cnt1; i++)            for (int j=0; j<cnt1; j++)                dis[i][j]=INF;        bool flag;        for (int i=0; i<cnt1; i++)        {            for (int j=i+1; j<cnt1; j++)            {                Line tmp;                tmp=Line(point1[i],point1[j]);                flag=true;                for (int l=0; l<cnt2; l++)                {                    int k;                    k=intersect(tmp,line[l]);                    if (k!=0) {flag=false; break;}                }                if (flag==true)                {                    dis[i][j]=getDist(point1[i],point1[j]);                }            }        }        for (int k=0;k<cnt1;k++)            for (int i=0;i<cnt1;i++)                if (dis[i][k] < INF)                for (int j=0;j<cnt1;j++)                if (dis[k][j] < INF)                    dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);        printf("%.2lf\n",dis[0][cnt1-1]);    }    return 0;}