Cod sursa(job #1554363)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 21 decembrie 2015 12:19:43
Problema Bibel Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <cstdio>
#include <algorithm>

#define DIM 19
#define INF 1000000000
#define x first
#define y second
using namespace std;

int N, minim, k, Min[DIM], NextMin[DIM], P[1 << DIM];
int D[1 << DIM][DIM], A[DIM], cod, X, Y;
pair <int, int> B[DIM*DIM][DIM]; int ok;

int getDistance (pair <int, int> A, pair <int, int> B) {
    return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
}

int getAnswer (int msk, int i) {

    if (D[msk][i] == INF) {
        int val = msk, pos;

        while (val) {
            pos = P[(val & (-val))];
            if (pos != i)
                D[msk][i] = min (D[msk][i], getAnswer (msk - (1 << i), pos) + getDistance (B[k][pos], B[k][i]));
            val -= (val & (-val));
        }
    }

    return D[msk][i];
}

int main () {

    freopen ("bibel.in" ,"r", stdin );
    freopen ("bibel.out","w", stdout);

    for (int i = 0; i < 18; i ++)
        P[1 << i] = i;

    ok = 1;
    while (ok) {
        scanf ("%d", &cod);

        switch (cod) {
            case 0: {
                scanf ("%d %d", &X, &Y);
                B[N][A[N]++] = make_pair (X, Y);
                break;
            }
            case 1: {
                N ++;
                break;
            }
            case 2: {
                ok = 0;
                break;
            }
        }
    }

    for (int msk = 0; msk < (1 << A[0]); msk ++) {
        for (int i = 0; i < A[0]; i ++)
            D[msk][i] = INF;
    }
    for (int i = 0; i < A[0]; i ++)
        D[1 << i][i] = getDistance (make_pair (0, 0), B[0][i]);

    for (int i = 0; i < A[0]; i ++)
        Min[i] = getAnswer ((1 << A[0]) - 1, i);

    minim = INF;
    for (int i = 0; i < A[0]; i ++)
        minim = min (minim, Min[i]);

    printf ("%d\n", minim);

    for (k = 1; k < N; k ++) {

        for (int i = 0; i < A[k]; i ++)
            NextMin[i] = INF;

        for (int msk = 0; msk < (1 << A[k]); msk ++) {
                for (int i = 0; i < A[k]; i ++)
                    D[msk][i] = INF;
            }

        for (int j = 0; j < A[k-1]; j ++)
        for (int i = 0; i < A[k-0]; i ++)
            D[1 << i][i] = min (D[1 << i][i], getDistance (B[k-1][j], B[k][i]) + Min[j]);

        for (int i = 0; i < A[k]; i ++)
            NextMin[i] = getAnswer ((1 << A[k]) - 1, i);

        for (int i = 0; i < A[k]; i ++)
            Min[i] = NextMin[i];

        minim = INF;
        for (int i = 0; i < A[k]; i ++)
            minim = min (minim, Min[i]);

        printf ("%d\n", minim);
    }

    return 0;
}