/* NMiP, task E: islands */ #include #include #include typedef int * pint; typedef long * plong; long dist(int x1, int y1, int x2, int y2) { return ((long)x1 - (long)x2) * ((long)x1 - (long)x2) + ((long)y1 - (long)y2) * ((long)y1 - (long)y2); } int main() { FILE *f, *g; int cases, n, i, j, k, l; long dst, maxdist, mindist; int mini, minj, cj, ck; int **x, **y, *p, *connected; long **d; double length; f = fopen("islands.in", "r"); g = fopen("islands.out", "w+"); fscanf(f, "%d", &cases); while (cases--) { /* number of polygons */ fscanf(f, "%d", &n); /* create polygon arrays */ p = new int[n]; x = new pint[n]; y = new pint[n]; d = new plong[n]; /* read all polygons */ for (i = 0; i < n; i++) { fscanf(f, "%d", &p[i]); x[i] = new int[p[i]]; y[i] = new int[p[i]]; d[i] = new long[n]; for (j = 0; j < p[i]; j++) fscanf(f, "%d%d", &x[i][j], &y[i][j]); } /* find the distances between islands, we must check all as the polygons can be non-convex */ for (i = 0; i < n; i++) for (j = i + 1; j < n; j++) { mindist = dist(x[i][0], y[i][0], x[j][0], y[j][0]); mini = minj = 0; for (k = 0; k < p[i]; k++) for (l = 0; l < p[i]; l++) if ((dst = dist(x[i][k], y[i][k], x[j][l], y[j][l])) < mindist) { mindist = dst; mini = k; minj = l; } else if (dst > maxdist) maxdist = dst; d[i][j] = d[j][i] = mindist; } maxdist += 1; /* and now it's just a standard minimum spanning tree... */ connected = new int[n]; for (i = 0; i < n; i++) connected[i] = 0; connected[0] = 1; length = 0; for (i = 0; i < n - 1; i++) { dst = maxdist; for (j = 0; j < n; j++) for (k = 0; k < n; k++) { if (connected[j] + connected[k] == 1) if (d[j][k] < dst) { cj = j; ck = k; dst = d[j][k]; } } connected[cj] = connected[ck] = 1; length += sqrt((double)d[cj][ck]); } fprintf(g, "The minimal interconnect consists of %d bridges\n", n - 1); fprintf(g, "with a total length of %.3lf.\n", length); /* deallocate all arays used in this case */ for (i = 0; i < n; i++) { delete [] x[i]; delete [] y[i]; delete [] d[i]; } delete [] connected; delete [] x; delete [] y; delete [] p; delete [] d; } fclose(f); fclose(g); return 0; }