题目抽象:给你一些点,和一些阻碍连边的线段。问原点到终点最短的几何距离。
分析:预处理见图之后,跑最短路。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 using namespace std; 6 const int INF = 0X5FFFFFFF; 7 const int MS = 1005; 8 const int MS2 = 100; 9 10 struct point { 11 double x, y; 12 // point(double _x = 0, double _y = 0) : x(_x), y(_y) {} 13 //长期不更新编译器的oj,可能不支持pioint{}初始化。 可以改为构造函数point()初始化。 14 }points[MS]; 15 struct edge { 16 int u, v; 17 double w; 18 }edges[MS * MS]; 19 20 int pSize, eSize; 21 int n; 22 23 double w[MS], wY[MS][4]; 24 double dis[MS]; 25 26 double D(const point &a, const point &b) { 27 return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); 28 } 29 30 double C(const point &a, const point &b, const point &c) { 31 return (c.y - a.y) * (a.x - b.x) - (a.y - b.y) * (c.x - a.x); 32 } 33 34 bool isOk(const point &a,const point &b) { 35 if (a.x >= b.x) 36 return false; 37 int i = 0; 38 while (i < n && w[i] <= a.x) 39 i++; 40 while (i < n && w[i] < b.x ) { 41 if (C(a, b, point{w[i],0}) * C(a, b, point{w[i],wY[i][0]}) < 0) 42 return false; 43 if (C(a, b, point{w[i],wY[i][1]}) * C(a, b, point{w[i], wY[i][2]}) < 0) 44 return false; 45 if (C(a, b, point{w[i], wY[i][3]}) * C(a, b, point{w[i], 10.0}) < 0) 46 return false; 47 i++; 48 } 49 return true; 50 } 51 52 int input() { 53 scanf("%d", &n); 54 if (n == -1) 55 return 0; 56 pSize = 0; 57 points[pSize].x = 0; 58 points[pSize++].y = 5; 59 for (int i = 0; i < n; i++) { 60 scanf("%lf", &w[i]); 61 for (int j = 0;j < 4;j ++) { 62 points[pSize].x = w[i]; 63 scanf("%lf", &wY[i][j]); 64 points[pSize++].y = wY[i][j]; 65 } 66 } 67 points[pSize].x = 10; 68 points[pSize++].y = 5; 69 70 eSize = 0; 71 for (int i = 0; i < pSize; i++) { 72 for (int j = i + 1;j < pSize; j++) { 73 if (isOk(points[i], points[j])) { 74 edges[eSize].u = i; 75 edges[eSize].v = j; 76 edges[eSize++].w = D(points[i], points[j]); 77 } 78 } 79 } 80 return 1; 81 } 82 83 void Bellman(int v0) { 84 for (int i = 0; i < pSize; i++) 85 dis[i] = INF; // fill(dis,dis + pSize, INF ) 86 dis[v0] = 0.0; 87 int flag = 1; 88 for (int t = 1; t < pSize && flag; t++) { 89 flag = 0; 90 for (int i = 0; i < eSize; i++) { 91 if (dis[edges[i].u] + edges[i].w < dis[edges[i].v]) { 92 dis[edges[i].v] = dis[edges[i].u] + edges[i].w; 93 flag = 1; 94 } 95 } 96 } 97 } 98 99 int main() { 100 while (input()) { 101 Bellman(0); 102 printf("%.2lf\n", dis[pSize -1]); 103 } 104 return 0; 105 }
时间: 2024-10-12 17:49:13