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 |
Re:500题,0ms,1A留念!!第500题献给了 图论+计算几何,留下详解以留念In Reply To:500题,0ms,1A留念!!第500题献给了 图论+计算几何,留下详解以留念 Posted by:vjubge4 at 2019-06-26 10:10:03 > 计算几何 + 图论,线段相交判定 + 最短路径算法。 > 考虑如何建图?将图中线段的每一个端点,起始点和终点作为图中的边,考察对于任意节点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