Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

500题,0ms,1A留念!!第500题献给了 图论+计算几何,留下详解以留念

Posted by vjubge4 at 2019-06-26 10:10:03 on Problem 1556
计算几何 + 图论,线段相交判定 + 最短路径算法。
考虑如何建图?将图中线段的每一个端点,起始点和终点作为图中的边,考察对于任意节点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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator