Cod sursa(job #2020901)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 12 septembrie 2017 01:27:36
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.71 kb
#include <cstdio>
#include <algorithm>

FILE *fin = fopen("bibel.in", "r"), *fout = fopen("bibel.out", "w");

#define MAXN 17
#define MAXK 200

#define INF 2000 * 1000 * 1000

int x[MAXN], y[MAXN], a[MAXK], b[MAXK];
int dp[1 << MAXN][MAXN], r[MAXK], ans;

inline int cost(int p, int q) {
    return (a[p] - a[q]) * (a[p] - a[q]) + (b[p] - b[q]) * (b[p] - b[q]);
}

inline void calc(int n, int k) {
    for (int i = 1; i < (1 << n); i++) {
        for (int j = 0; j < n; j++) if ((i & (1 << j)) && i != (1 << j)) {
            dp[i][j] = INF;
            for (int p = 0; p < n; p++)
                if (p != j && (i & (1 << p)))
                    dp[i][j] = std::min(dp[i][j], dp[i ^ (1 << j)][p] + cost(k + j, k + p));
        }
    }

    ans = INF;
    for (int i = 0; i < n; i++) {
        r[k + i] = dp[(1 << n) - 1][i];
        ans = std::min(ans, r[k + i]);
    }
}

int main() {
    int t, n = 0, k = 1, st = 0;
    fscanf(fin, "%d", &t);

    while (t != 2) {
        if (t == 0) {
            fscanf(fin, "%d%d", &x[n], &y[n]);
            a[k + n] = x[n];
            b[k + n] = y[n];
            n++;
        } else {
            if (n != 0) {
                for (int i = 0; i < n; i++) {
                    dp[1 << i][i] = cost(k + i, st) + r[st];
                    for (int j = st + 1; j < k; j++)
                        dp[1 << i][i] = std::min(dp[1 << i][i], cost(k + i, j) + r[j]);
                }

                calc(n, k);

                st = k;
                k += n;
                n = 0;
            }

            fprintf(fout, "%d\n", ans);
        }

        fscanf(fin, "%d", &t);
    }

    fclose(fin);
    fclose(fout);
    return 0;
}