| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
500题,0ms,1A留念!!第500题献给了 图论+计算几何,留下详解以留念计算几何 + 图论,线段相交判定 + 最短路径算法。
考虑如何建图?将图中线段的每一个端点,起始点和终点作为图中的边,考察对于任意节点i和节点j,如果i和j之间没有墙,则建立一条长度为几何距离的边,否则不建立边。
如何判断i和j之间是否有墙?创建一条起点为i终点为j的线段,遍历全部的墙(线段),利用计算几何的方法,判断线段是否相交即可。建图完成后,
运行从开始点到终点的Dijkstra算法即可,源代码见下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const double inf = 1e20;
const double eps = 1e-8;
const double pi = acos(-1);
int cmp (double a, double b) {
if(fabs(a - b) < 0) {
return 0;
}
if(a > b) {
return 1;
} else {
return -1;
}
}
double add(double a, double b) {
if(abs(a + b) < eps * (abs(a) + abs(b))) {
return 0;
}
return a + b;
}
struct P {
double x, y;
P() {}
P(double x, double y): x(x), y(y) {}
P operator + (P p) {
return P(add(x, p.x), add(y, p.y));
}
P operator - (P p) {
return P(add(x, -p.x), add(y, -p.y));
}
P operator * (double d) {
return P(x * d, y * d);
}
double operator * (P p) {
return add(x * p.x, y * p.y);
}
double operator ^ (P p) {
return add(x * p.y, -y * p.x);
}
double dist(P p) {
return sqrt( (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) );
}
};
struct L {
P s, e;
L() {}
L(double a, double b, double c, double d) : s(a, b), e(c, d) {}
L(P s, P e): s(s.x, s.y), e(e.x, e.y) {}
bool on(P p) {
return ((p - s) ^ (p - e)) == 0 && ((p - s) * (p - e)) <= 0;
}
P intersection(L l) {
return s + (e - s) * (((l.s - l.e) ^ (s - l.s)) / ((l.s - l.e) ^ (s - e)));
}
bool cross(L l) {
P p = intersection(l);
return on(p) && l.on(p);
}
};
char buf[1024];
vector<P> arr_P;
vector<L> arr_L;
struct edge {
int to;
double d;
};
typedef pair<double, int> Node;
vector<edge> G[2048];
double dist[2048];
int N;
int V;
double dijkstra() {
fill(dist, dist + V, inf);
priority_queue<Node, vector<Node>, greater<Node> > que;
dist[0] = 0;
que.push(Node(0, 0));
while(!que.empty()) {
Node p = que.top();
que.pop();
int v = p.second;
if(dist[v] < p.first) {
continue;
}
for(int i = 0; i < G[v].size(); i ++) {
edge & e = G[v][i];
if(dist[e.to] > dist[v] + e.d) {
dist[e.to] = dist[v] + e.d;
que.push(Node(dist[e.to], e.to));
}
}
}
return dist[V - 1];
}
int main() {
while(true) {
scanf("%d", &N);
getchar();
if(N == -1) {
break;
}
arr_P.clear();
arr_L.clear();
for(int i = 0; i < 2048; i ++) {
G[i].clear();
}
arr_P.push_back(P(0, 5));
for(int i = 0; i < N; i ++) {
gets(buf);
int index = 0;
int len = strlen(buf);
double loc;
sscanf(buf,"%lf", &loc);
while(index < len && buf[index] != ' ') {
index ++;
}
index ++;
double a, b;
sscanf( buf + index,"%lf", &a);
arr_P.push_back(P(loc, a));
arr_L.push_back(L(loc, 0, loc, a));
while(index < len) {
while(index < len && buf[index] != ' ') {
index ++;
}
index ++;
if(index < len) {
sscanf( buf + index, "%lf", &a);
}
while(index < len && buf[index] != ' ') {
index ++;
}
index ++;
if(index >= len) {
arr_P.push_back(P(loc, a));
arr_L.push_back(L(loc, a, loc, 10));
} else {
sscanf(buf + index, "%lf", &b);
arr_P.push_back(P(loc, a));
arr_P.push_back(P(loc, b));
arr_L.push_back(L(loc, a, loc, b));
}
}
}
arr_P.push_back(P(10, 5));
V = arr_P.size();
for(int i = 0; i < V; i ++) {
for(int j = i + 1; j < V; j ++) {
if(arr_P[j].x == arr_P[i].x) {
continue;
}
L line(arr_P[i], arr_P[j]);
bool able = true;
for(int k = 0; k < arr_L.size(); k ++) {
if(arr_L[k].s.x > arr_P[i].x && arr_L[k].s.x < arr_P[j].x) {
if(line.cross(arr_L[k])) {
able = false;
break;
}
}
}
if(able) {
edge e;
e.to = j;
e.d = arr_P[i].dist(arr_P[j]);
G[i].push_back(e);
}
}
}
printf("%.2f\n", dijkstra());
}
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator