写一道POJ的题就要吐槽一次编译
题目
解题思路
对于所有点对,判断能不能建边。
如果有某个墙挡住了这条边,那么不能建边。即判断两线段是否相交,不能算端点。
代码
#include <map>
#include <queue>
#include <cmath>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2500;
typedef struct Point
{
double x, y;
Point operator-(const Point &temp) const
{
Point T;
T.x = x - temp.x;
T.y = y - temp.y;
return T;
}
} Vector;
double cross(Vector A, Vector B)
{
return A.x * B.y - A.y * B.x;
}
double dot(Vector A, Vector B)
{
return A.x * B.x + A.y * B.y;
}
double check(Point a, Point b, Point c, Point d)
{
Vector V1 = b - a;
Vector V2 = c - a;
Vector V3 = d - a;
Vector V4 = c - d;
Vector V5 = a - d;
Vector V6 = b - d;
if (cross(V1, V3) * cross(V1, V2) < 0 && cross(V4, V5) * cross(V4, V6) < 0)
return 1;
return 0;
}
int n;
int ct, cnt;
Point p1[N];
Point p2[N];
Point p[N];
vector<pair<int, double>> vec[N];
double dis[N];
bool vis[N];
void dij()
{
for (int i = 1; i <= cnt; i++)
dis[i] = 1e18, vis[i] = 0;
dis[1] = 0;
priority_queue<pair<double, int>> q;
q.push(make_pair(0, 1));
while (q.size())
{
double w = -q.top().first;
int u = q.top().second;
q.pop();
if (vis[u])
continue;
vis[u] = 1;
int m = vec[u].size();
for (int i = 0; i < m; i++)
{
if (!vis[vec[u][i].first])
if (vec[u][i].second + w < dis[vec[u][i].first])
{
dis[vec[u][i].first] = vec[u][i].second + w;
q.push(make_pair(-dis[vec[u][i].first], vec[u][i].first));
}
}
}
printf("%.2f\n", dis[cnt]);
}
Point temp;
void solve()
{
ct = cnt = 0;
temp.x = 0, temp.y = 5;
p[++cnt] = temp;
for (int i = 1; i <= n; i++)
{
double x;
scanf("%lf", &x);
double y[6];
for (int i = 1; i <= 4; i++)
{
scanf("%lf", &y[i]);
temp.x = x, temp.y = y[i];
p[++cnt] = temp;
}
temp.x = x, temp.y = 0;
p1[++ct] = temp;
temp.x = x, temp.y = y[1];
p2[ct] = temp;
temp.x = x, temp.y = y[2];
p1[++ct] = temp;
temp.x = x, temp.y = y[3];
p2[ct] = temp;
temp.x = x, temp.y = y[4];
p1[++ct] = temp;
temp.x = x, temp.y = 10;
p2[ct] = temp;
}
temp.x = 10, temp.y = 5;
p[++cnt] = temp;
for (int i = 1; i <= cnt; i++)
vec[i].clear();
for (int i = 1; i <= cnt; i++)
{
for (int j = i + 1; j <= cnt; j++)
{
bool f = 1;
for (int k = 1; k <= ct; k++)
if (check(p[i], p[j], p1[k], p2[k])) //是否有线段挡着
{
f = 0;
break;
}
if (f) //如果没有线段挡着 建边i-j
{
vec[i].push_back(make_pair(j, sqrt(dot(p[i] - p[j], p[i] - p[j]))));
// vec[j].push_back(make_pair(i, sqrt(dot(p[i] - p[j], p[i] - p[j]))));
}
}
}
dij();//建图完毕,跑最短路
}
int main()
{
while (scanf("%d", &n) && n != -1)
solve();
return 0;
}