加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 1556 计算几何 线段相交(不带端点)+最短路

(2010-07-19 16:43:02)
标签:

poj

pku

1556

it

分类: 计算几何

题目描述:给你一个类似迷宫的东西,围墙的坐标都告诉你,然你求从起点到终点的最短距离。

解题报告:把每段围墙的2个端点都看作图中的节点,扫描每2个端点,如果这两个端点构成的线段和所有的围墙都不相交,那么这两个端点可达,距离就是这个线段的距离。

然后求最短路即可。

代码如下:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
#define Max 2000000000
#define size 200
int n, cnt;
struct pint{double x, y;}x[size];
double g[size][size], d[size], pos;
bool vst[size][size], vst2[size];
int eps(double xx)
{
    if (fabs(xx) <= 0.00001) return 0;
    else if (xx > 0) return 1;
    else return -1;
}
double direction(pint p1, pint p2, pint p3)
{
    return (p3.x - p1.x) * (p2.y - p1.y) - (p2.x - p1.x) * (p3.y - p1.y);
}
bool online(pint p1, pint p2, pint p3)
{
    return (p3.x >= min(p1.x, p2.x) && p3.x <= max(p1.x, p2.x) && p3.y >= min(p1.y, p2.y) && p3.y <= max(p1.y, p2.y));
}
bool insect(pint p1, pint p2, pint p3, pint p4)
{
    double d1 = direction(p3, p4, p1);
    double d2 = direction(p3, p4, p2);
    double d3 = direction(p1, p2, p3);
    double d4 = direction(p1, p2, p4);
    if (eps(d1) * eps(d2) < 0 && eps(d3) * eps(d4) < 0) return true;
    return false;
}
void input()
{
    x[0].x = 0, x[0].y = 5;
    cnt = 1;
    for(int i = 0; i < n; i++)
    {
        scanf("%lf", &pos);
        x[cnt].x = pos, x[cnt++].y = 0;
        for(int j = 0; j < 4; j++)
        {
            x[cnt].x = pos;
            scanf("%lf", &x[cnt++].y);
        }
        x[cnt].x = pos, x[cnt++].y = 10;
    }
    x[cnt].x = 10, x[cnt++].y = 5;
}
void build()
{
    memset(vst, 0, sizeof(vst));
    for(int i = 0; i < cnt; i++)
        for(int j = i + 1; j < cnt; j++)
        {
            bool flag = true;
            for(int k = 1; 2 * k < cnt; k++)
                if (insect(x[i], x[j], x[k * 2 - 1], x[k * 2]))
                {
                    flag = false;
                    break;
                }
            if (flag)
            {
                vst[j][i] = vst[i][j] = 1;
                g[i][j] = g[j][i] = sqrt((x[i].x - x[j].x) * (x[i].x - x[j].x) + (x[i].y - x[j].y) * (x[i].y - x[j].y));
            }
        }
}
double shortest()
{
    memset(vst2, 0, sizeof(vst2));
    vst2[0] = 1;
    for(int i = 1; i < cnt; i++)
        if (vst[0][i]) d[i] = g[0][i];
        else d[i] = Max;
    for(int i = 0; i < cnt; i++)
    {
        double Min = Max;int mid = -1;
        for(int j = 1; j < cnt; j++)
            if (!vst2[j] && d[j] < Min)
            {
                Min = d[j];
                mid = j;
            }
        if(mid == -1) break;
        vst2[mid] = 1;
        for(int j = 1; j < cnt; j++)
            if (!vst2[j] && vst[mid][j] && d[mid] + g[mid][j] < d[j])
                d[j] = d[mid] + g[mid][j];
    }
    return d[cnt - 1];
}
int main()
{
    while(scanf("%d", &n) && n != -1)
    {
        input();
        build();
        printf("%.2f\n", shortest());
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有