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:backupIn Reply To:backup Posted by:yygy at 2023-06-12 23:36:24 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <time.h> #include <mutex> #include <stack> #include <cmath> #include <set> #include <map> #include <queue> #include <string> #include <string.h> #include <vector> #include <stdio.h> #include <algorithm> using namespace std; typedef unsigned long long llu; typedef long long lld; const int MAXN = 2e5 + 10; const int INF = 1e9; int gcd(int a, int b) { if (a == 0)return b; if (b == 0)return a; if (a % b == 0)return b; return gcd(b, a % b); } typedef std::pair<int, int> Point; int last = 0; std::map<Point, int> id; struct Segment { Point begin; Point end; }; Segment segments[512]; void ReadPoint(Point& s) { scanf("%d%d", &s.first, &s.second); } std::vector<Point> sto; int QueryId(const Point& s) { const std::map<Point, int>::iterator iter = id.find(s); if (iter == id.end()) { sto.push_back(s); id[s] = last; last++; return last - 1; } else { return iter->second; } } Point MakeVector(const Point& a, const Point& b) { return std::make_pair(b.first - a.first, b.second - a.second); } int Cross(const Point& ab, const Point& cd) { return ab.first * cd.second - ab.second * cd.first; } int Dot(const Point& a, const Point& b) { return a.first * b.first + a.second * b.second; } bool OnSegment(const Point& p, const Point& a, const Point& b) { const Point& ap = MakeVector(a, p); const Point& ab = MakeVector(a, b); if (Cross(ap, ab) == 0) { const Point& pa = MakeVector(p, a); const Point& pb = MakeVector(p, b); return Dot(pa, pb) <= 0; } return false; } bool Shared(const Point& a, const int firbidden, const int n) { for (int i = 0; i < n; i++) { if (firbidden == i) { continue; } if (OnSegment(a, segments[i].begin, segments[i].end)) { return true; } } return false; } Point origin; int SqrDis(const Point& a, const Point& b) { int dx = a.first - b.first; int dy = a.second - b.second; return dx * dx + dy * dy; } bool cmp(const Point& a, const Point& b) { return SqrDis(a, origin) < SqrDis(b, origin); } double g[512][512]; bool Blocked(const Point& a, const Point& b, const std::vector<Segment>& signs) { for (int i = 0; i < signs.size(); i++) { const Segment& sign = signs[i]; const Point& ab = MakeVector(a, b); if (OnSegment(sign.begin, a, b)) { const Point& v = MakeVector(sign.begin, sign.end); if (Dot(ab, v) >= 0) { return false; } } if (OnSegment(sign.end, a, b)) { const Point& v = MakeVector(sign.end, sign.begin); if (Dot(ab, v) >= 0) { return false; } } } return false; } int pre[512]; double dis[512]; double Dij(int s, int t, int n) { for (int i = 0; i < n; i++) { dis[i] = INF; } dis[s] = 0; bool vis[512] = { false }; pre[s] = -1; for (int i = 0; i < n; i++) { int minId = -1; double minDis = INF; for (int j = 0; j < n; j++) { if (!vis[j] && dis[j] < minDis) { minId = j; minDis = dis[j]; } } if (minId == -1) { return dis[t]; } for (int j = 0; j < n; j++) { if (dis[minId] + g[minId][j] < dis[j]) { dis[j] = dis[minId] + g[minId][j]; pre[j] = minId; } } } return dis[t]; } int main(int argc, char* argv[]) { int n; Point s, t; while (cin >> n && n>0) { sto.clear(); ReadPoint(s); ReadPoint(t); id.clear(); last = 0; QueryId(s); QueryId(t); for (int i = 0; i < n; i++) { ReadPoint(segments[i].begin); ReadPoint(segments[i].end); } std::vector<Segment> streets; std::vector<Segment> signs; //找出是stree的部分,两个端点都被共享 for (int i = 0; i < n; i++) { if (Shared(segments[i].begin, i, n) && Shared(segments[i].end, i, n)) { streets.push_back(segments[i]); } else { signs.push_back(segments[i]); } } for (int i = 0; i < last; i++) { for (int j = 0; j < last; j++) { g[i][j] = INF; } } //对每一个street,计算出被分成了几段,对于每一段检测是否可通行 for (int streetId = 0; streetId < streets.size(); streetId++) { const Segment& street = streets[streetId]; std::vector<Point> points; points.push_back(street.begin); points.push_back(street.end); for (int otherId = 0; otherId < streets.size(); otherId++) { const Segment& other = streets[otherId]; if (OnSegment(other.begin, street.begin, street.end)) { points.push_back(other.begin); } if (OnSegment(other.end, street.begin, street.end)) { points.push_back(other.end); } } origin = street.begin; //先进行排序 std::sort(points.begin(), points.end()); points.erase(std::unique(points.begin(), points.end()), points.end()); for (int roadId = 0; roadId + 1 < points.size(); roadId++) { const Point& a = points[roadId]; const Point& b = points[roadId + 1]; int idA = QueryId(a); int idB = QueryId(b); if (!Blocked(a, b, signs)) { g[idA][idB] = sqrt(SqrDis(a, b)); } if (!Blocked(b, a, signs)) { g[idB][idA] = sqrt(SqrDis(b, a)); } } } //跑一下最短路 //#TODO int sId = QueryId(s); int tId = QueryId(t); double dis = Dij(sId, tId, last); if (dis < INF) { std::vector<int> trace; while (tId != -1) { trace.push_back(tId); tId = pre[tId]; } std::reverse(trace.begin(), trace.end()); for (int i = 0; i < trace.size(); i++) { const Point& ps = sto[trace[i]]; printf("%d %d\n", ps.first, ps.second); } puts("0"); } else { puts("-1"); } } return 0; } /* */ Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator