The minimum turn left method plan view of FIG coupling pairs, and scanning lines point positioning.
Both algorithms can see this blog
This figure may be a case containing a profile of another profile, then put the upper left corner point of a line can be connected, the scanning line is achieved.
Yourself understand the algorithm code or not write, computational geometry too weak. . . The board can be used as well to consolidate. . .
#include <bits/stdc++.h> #define db double const db eps = 1e-8; const int N = 2e4 + 7; const int XN = 1e4; inline int sign(db x) { return x < -eps ? -1 : x > eps; } inline int cmp(db x, db y) { return sign(x - y); } struct P { int x, y; P(int _x = 0, int _y = 0): x(_x), y(_y) {} P operator + (const P &p) const { return {x + p.x, y + p.y}; } P operator - (const P &p) const { return {x - p.x, y - p.y}; } inline int det(const P &p) { return x * p.y - y * p.x; } inline int dot(const P &p) { return x * p.x + y * p.y; } inline void read() { scanf("%d%d", &x, &y); } int quad() { return y > 0 || (y == 0 && x >= 0); } } point[N]; std::map<int, int> mp[N * 2]; std::vector<int> nxt[N]; int n, m, point_cnt, country[N]; struct L { P st, ed, dir; int x, y; L() {} L(P st_, P ed_, int x_, int y_) { st = st_, ed = ed_, x = x_, y = y_; dir = ed - st; } } line[N * 5]; bool agcmp(int x, int y) { P p = line[x].dir, q = line[y].dir; if (p.quad() != q.quad()) return p.quad() < q.quad(); return p.det(q) > 0; } struct Seg { int u, v, type, id; Seg () {} Seg(int u, int v, int type): u(u), v(v), type(type) {} bool operator < (const Seg &p) const { if (point[u].x != point[p.u].x) return point[u].x < point[p.u].x; return type < p.type; } } Themselves [N * 5 ]; struct Cmp { bool operator () (const Seg &a, const Seg &b) { int aa = (point[b.v] - point[a.u]).det(point[b.u] - point[a.u]), bb = (point[b.v] - point[a.v]).det(point[b.u] - point[a.v]); int cc = (point[a.v] - point[b.u]).det(point[a.u] - point[b.u]), dd = (point[a.v] - point[b.v]).det(point[a.u] - point[b.v]); return (aa < 0 && bb <= 0) || (aa <= 0 && bb < 0) || (cc > 0 && dd >= 0) || (cc >= 0 && dd > 0); } }; int getid(int x, int y) { x += XN; if (mp[x].count(y)) return mp[x][y]; point[++point_cnt] = P(x - XN, y); return mp[x][y] = point_cnt; } std::set<Seg, Cmp> st; bool vis[N]; int mst; void edit(int id) { vis[id] = 1; if (point[id].y > point[mst].y || (point[id].y == point[mst].y && point[id].x < point[mst].x)) mst = id; for (int i = 0; i < nxt[id].size(); i++) { int x = line[nxt[id][i]].y; if (!vis[x]) edit(x); } } void connect() { int cnt = 0; for (int i = 1; i <= point_cnt; i++) { if (nxt[i].size() && !vis[i]) { mst = i; edit(i); out [ ++ cnt] = Seg (MST, MST, 2 ); } } for (int i = 1; i <= m; i++) if (line[i].st.x < line[i].ed.x) out [ ++ cnt] = Seg (line [i] .x, line [i] .Y, 1 ), up [++ cnt] = Seg (line [i] .Y, line [i] .x, 0 ); std::sort(seg + 1, seg + 1 + cnt); for (int i = 1; i <= cnt; i++) { if (seg[i].type == 1) { st.insert(seg[i]); } Else if (up [i] .Type == 0 ) { st.erase (st.find (Seg (out [i] .v, out [i] .u, 1 ))); } else { std::set<Seg, Cmp>::iterator it = st.lower_bound(seg[i]); if (it == st.begin()) continue; --it; int u = it->u, v = seg[i].u; line[++m] = L(point[u], point[v], u, v); nxt[u].push_back(m); line[++m] = L(point[v], point[u], v, u); nxt[v].push_back(m); } } } int f, out, tag[N]; inline int ops(int x) { return (x & 1) ? (x + 1) : (x - 1); } void dfs(int index, int id) { tag[index] = id; int st = line[index].x, ed = line[index].y; int area = point[st].det(point[ed]); while (st != ed) { std::vector<int>::iterator it = std::upper_bound(nxt[ed].begin(), nxt[ed].end(), ops(index), agcmp); --it; if (it == nxt[ed].begin()) it = nxt[ed].end(); --it; index = *it; int j = line[index].y; area += point[ed].det(point[j]); ed = j; tag[index] = id; } if (area < 0) out = id; } int belong[N]; bool G[670][670]; void scanline() { st.clear(); int cnt = 0; for (int i = 1; i <= n; i++) seg[++cnt] = Seg(country[i], country[i], 2); for (int i = 1; i <= m; i++) if (line[i].st.x < line[i].ed.x) out [ ++ cnt] = Seg (line [i] .x, line [i] .Y, 1 ), out [cnt] .id = tag [ops (i)], out [++ cnt] = Seg ( line [i] .Y, line [i] .x, 0 ); std::sort(seg + 1, seg + 1 + cnt); for (int i = 1; i <= cnt; i++) { if (seg[i].type == 1) { st.insert(seg[i]); } Else if (up [i] .Type == 0 ) { st.erase (st.find (Seg (out [i] .v, out [i] .u, 1 ))); } else { std::set<Seg, Cmp>::iterator it = --st.upper_bound(seg[i]); belong[seg[i].u] = it->id; } } } int year [ 670 ]; int main () { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { int x, y; scanf("%d%d", &x, &y); country[i] = getid(x, y); } for (int i = 1; i <= m; i++) { P a, b; a.read(); b.read(); int x = getid(a.x, a.y), y = getid(b.x, b.y); line[i * 2 - 1] = L(a, b, x, y); line[i * 2] = L(b, a, y, x); nxt[x].push_back(i * 2 - 1); nxt[y].push_back(i * 2); } m *= 2; connect(); for (int i = 1; i <= point_cnt; i++) std::sort(nxt[i].begin(), nxt[i].end(), agcmp); for (int i = 1; i <= m; i++) if (!tag[i]) dfs(i, ++f); scanline(); for (int i = 1; i <= m; i += 2) { if (tag[i] != out && tag[i + 1] != out) G [tag [i]] [tag [i + 1 ]] = G [tag [i + 1 ]] [tag [i]] = 1 ; } for (int i = 1; i <= n; i++) { int res = 0; for (int j = 1; j <= n; j++) if (i != j && G[belong[country[i]]][belong[country[j]]]) { years [ ++ res] = j; } printf("%d", res); for (int j = 1; j <= res; j++) printf(" %d", ans[j]); puts(""); } return 0; }