Time Limit: 0.25 s
Space limit: 4 m
Question:
There are N points in a plane coordinate. Now you need to use these N points to construct a closed graph. This graph must meet the following conditions:
1. This image should be closed;
2. A vertex on a graph can only be a given vertex, and each vertex can only be used once;
3. The two edges connected to each vertex must be perpendicular to each other;
4. Each side must be parallel to the coordinate axis;
5. Each line cannot interwork with each other except the vertex;
6. the perimeter of the closed graph should be the smallest;
N ----- number of points
Next N points.
If yes, the minimum output length is 0.
Solution:
Focus on the fact that all edges in the image are parallel to the X or Y axis. To make all vertices right angle, you only need to sort all vertices first to the X axis and then to the Y axis.
It is easy to find that points in the same vertical line direction and the same horizontal line direction must be connected by two points.
Now the question is how to determine the intersection of line segments
If we have connected all vertical edges, then we connect the horizontal edges. The two points are (x1, Y, X2, Y ),
If a vertical edge (A, B1, A, B2) exists to make X1 <x <X2 and B1 <Y <B2, then the two edges intersect
Therefore, we can divide all the identical X in the sorting order into one group. If there are other groups in the X1 and X2 groups, even if X1 <x <X2,
Obtain the edge of those groups, determine whether B1 <Y <B2 is satisfied, and then determine whether there is only one closed curve, and check the set.
Reference code:
#include <cstdio>#include <iostream>#include <algorithm>using namespace std;const int INF = 11111;struct node {int x, y, Pxy, Pyx;};int f[INF];node Axy[INF], Ayx[INF];int pos[INF << 2], head[INF];int n, x, y, ans;int Find (int x) {if (f[x] != x) return f[x] = Find (f[x]);return x;}void getT (int a, int b) {f[Find (a)] = Find (b);}int cmpXY (node a, node b) {if (a.x == b.x) return a.y < b.y;return a.x < b.x;}int cmpYX (node a, node b) {if (a.y == b.y) return a.x < b.x;return a.y < b.y;}int make() {if (n & 1 ) return 0;for (int i = 2; i <= n; i += 2) {if (Axy[i - 1].x == Axy[i].x) {getT (i, i - 1);ans += Axy[i].y - Axy[i - 1].y;}else return 0;}for (int i = 2; i <= n; i += 2) {if (Ayx[i - 1].y == Ayx[i].y) {getT (Ayx[i - 1].Pxy, Ayx[i].Pxy);ans += Ayx[i].x - Ayx[i - 1].x;}else return 0;if (pos[Ayx[i - 1].x ] + 1 != pos[Ayx[i].x ])for (int j = head[pos[Ayx[i - 1].x ] + 1]; j < head[pos[Ayx[i].x ]] - 1; j += 2)if (Axy[j].y < Ayx[i].y && Ayx[i].y < Axy[j + 1].y) return 0;}for (int i = 2; i <= n; i++)if (Find(i) != Find(i-1))return 0;return ans;}int main() {scanf ("%d", &n);for (int i = 1; i <= n; i++) {scanf ("%d %d", &Axy[i].x, &Axy[i].y);Axy[i].x += INF, Axy[i].y += INF;}sort (Axy + 1, Axy + n + 1, cmpYX);for (int i = 1; i <= n; i++) {Axy[i].Pyx = i;Ayx[i] = Axy[i];}sort (Axy + 1, Axy + n + 1, cmpXY);int now = -1, t = 0;for (int i = 1; i <= n; i++) {Ayx[Axy[i].Pyx].Pxy = i, f[i] = i;if ( Axy[i].x != now ) {now = Axy[i].x, head[++t] = i;pos[now] = t;}}printf ("%d", make() );return 0;}