您的位置:首页 > 其它

The Doors 最短路 + 简单几何

2015-08-21 22:20 218 查看
                        The Doors

题目抽象:给你一些点,和一些阻碍连边的线段。问原点到终点最短的几何距离。

分析:预处理见图之后,跑最短路。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int INF = 0X5FFFFFFF;
const int MS = 1005;
const int MS2 = 100;

struct point {
double x, y;
// point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
//长期不更新编译器的oj,可能不支持pioint{}初始化。 可以改为构造函数point()初始化。
}points[MS];
struct edge {
int u, v;
double w;
}edges[MS * MS];

int pSize, eSize;
int n;

double w[MS], wY[MS][4];
double dis[MS];

double D(const point &a, const point &b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double C(const point &a, const point &b, const point &c) {
return (c.y - a.y) * (a.x - b.x) - (a.y - b.y) * (c.x - a.x);
}

bool isOk(const point &a,const point &b) {
if (a.x >= b.x)
return false;
int i = 0;
while (i < n && w[i] <= a.x)
i++;
while (i < n && w[i] < b.x ) {
if (C(a, b, point{w[i],0}) * C(a, b, point{w[i],wY[i][0]}) < 0)
return false;
if (C(a, b, point{w[i],wY[i][1]}) * C(a, b, point{w[i], wY[i][2]}) < 0)
return false;
if (C(a, b, point{w[i], wY[i][3]}) * C(a, b, point{w[i], 10.0}) < 0)
return false;
i++;
}
return true;
}

int input() {
scanf("%d", &n);
if (n == -1)
return 0;
pSize = 0;
points[pSize].x = 0;
points[pSize++].y = 5;
for (int i = 0; i < n; i++) {
scanf("%lf", &w[i]);
for (int j = 0;j < 4;j ++) {
points[pSize].x = w[i];
scanf("%lf", &wY[i][j]);
points[pSize++].y = wY[i][j];
}
}
points[pSize].x = 10;
points[pSize++].y = 5;

eSize = 0;
for (int i = 0; i < pSize; i++) {
for (int j = i + 1;j < pSize; j++) {
if (isOk(points[i], points[j])) {
edges[eSize].u = i;
edges[eSize].v = j;
edges[eSize++].w = D(points[i], points[j]);
}
}
}
return 1;
}

void Bellman(int v0) {
for (int i = 0; i < pSize; i++)
dis[i] = INF;     //  fill(dis,dis + pSize, INF )
dis[v0] = 0.0;
int flag = 1;
for (int t = 1; t < pSize && flag; t++) {
flag = 0;
for (int i = 0; i < eSize; i++) {
if (dis[edges[i].u] + edges[i].w < dis[edges[i].v]) {
dis[edges[i].v] = dis[edges[i].u] + edges[i].w;
flag = 1;
}
}
}
}

int main() {
while (input()) {
Bellman(0);
printf("%.2lf\n", dis[pSize -1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: