POJ 1556 The Doors 计算几何+MST

来源:互联网 发布:淘宝店铺层级怎么计算 编辑:程序博客网 时间:2024/03/29 06:02

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length.


Input

The input data for the illustrated chamber would appear as follows.

2
4 2 7 8 9
7 3 4.5 6 7

The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.


Output

The output file should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no blanks.


Sample Input

1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1


Sample Output

10.00

10.06


题意:一个10*10的坐标系下的房间,给出房间中的一些墙(给出的墙一定是两块连着上下部,一块在中间),要你求从(0,5)->(10,5)的最短路径长度。


分析:首先明确一点,如果(0,5)->(10,5)的直线距离上有墙相隔,那么最短路径中一定要经过那块墙的某个端点。那么对于给出的每块墙,却出端点,与其他端点建立一张图(注意建图时要判断两点的直线上是否被其他墙隔离),在这个图上找最短路即可。


PS:每个横坐标点的墙端点坐标一定为4个,那么这四个为一组就可以形成这个横坐标点的墙约束条件,数据小Floyd暴力跑过。

<span style="font-size:18px;">#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>using namespace std;#define INF 0x3f3f3f3fdouble g[1005][1005];struct node{    double x;    double y;} T[100005];int n;int cnt;void build(int a,int b){    if(T[a].x==T[b].x) return ;    int flag=1;    int l=a%4==0?a+1:a/4*4+5;    int r=b%4==0?b-3:b/4*4+1;    for(int i=l; i<r; i+=4)    {        double y=(T[b].y-T[a].y)/(T[b].x-T[a].x)*(T[i].x-T[a].x)+T[a].y;        if((y>=T[i].y&&y<=T[i+1].y)||(y>=T[i+2].y&&y<=T[i+3].y)) continue;        else flag=0;    }    if(flag)    {        g[a][b]=g[b][a]=sqrt((T[a].x-T[b].x)*(T[a].x-T[b].x)+(T[a].y-T[b].y)*(T[a].y-T[b].y));    }}void get_(){    for(int i=0; i<cnt-1; i++)    {        build(i,cnt-1);    }}int main(){    while(scanf("%d",&n)!=EOF)    {        if(n==-1) return 0;        for(int i=0; i<=100; i++)            for(int j=0; j<=100; j++)                g[i][j]=INF;        T[0].x=0,T[0].y=5;        cnt=1;        for(int i=1; i<=n; i++)        {            double x;            scanf("%lf",&x);            T[cnt].x=x;            scanf("%lf",&T[cnt].y);            cnt++;            get_();            T[cnt].x=x;            scanf("%lf",&T[cnt].y);            cnt++;            get_();            T[cnt].x=x;            scanf("%lf",&T[cnt].y);            cnt++;            get_();            T[cnt].x=x;            scanf("%lf",&T[cnt].y);            cnt++;            get_();        }        T[cnt].x=10;        T[cnt++].y=5;        for(int i=0; i<cnt-1; i++) build(i,cnt-1);        for(int k=0; k<cnt; k++)            for(int i=0; i<cnt; i++)                for(int j=0; j<cnt; j++)                    g[i][j]=g[j][i]=min(g[i][j],g[i][k]+g[k][j]);        printf("%.2lf\n",g[0][cnt-1]);    }    return 0;} </span>



0 0
原创粉丝点击