Cod sursa(job #118044)

Utilizator dominoMircea Pasoi domino Data 22 decembrie 2007 23:55:20
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <stdio.h>
#include <algorithm>
#include <vector>

using namespace std;

#define MAX_LEV 205
#define MAX_P 17
#define FIN "bibel.in"
#define FOUT "bibel.out"
#define mp make_pair
#define pb push_back
#define x first
#define y second
#define sqr(x) ((x)*(x))
#define dist(a, b) sqr(a.x-b.x)+sqr(a.y-b.y)
#define INF 0x3f3f3f3f

typedef pair<int, int> point;

int D[MAX_P][MAX_P], A[1<<MAX_P][MAX_P], bst[MAX_LEV][MAX_P], V[MAX_P], nv;
vector<point> P[MAX_LEV];

inline int min(int a, int b) { return a < b ? a : b; }

int main(void)
{
    int op, x, y, i, j, k, n, *v, lv = 0;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    P[0].pb(mp(0, 0));
    for (lv = 1; scanf("%d %d %d", &op, &x, &y) == 3; ++lv)
    {
        P[lv].pb(mp(x, y));
        while (scanf("%d", &op) == 1 && !op)
        {
            scanf("%d %d", &x, &y);
            P[lv].pb(mp(x, y));
        }

        n = P[lv].size();
        for (i = 0; i < n; ++i)
            for (j = 0; j < n; ++j)
                D[i][j] = dist(P[lv][i], P[lv][j]);


        for (i = 0; i < (1<<n); ++i)
            for (j = 0; j < n; ++j)
                A[i][j] = INF;
        for (i = 0; i < n; ++i)
            for (j = 0; j < P[lv-1].size(); ++j)
                A[1<<i][i] = min(A[1<<i][i], bst[lv-1][j]+dist(P[lv-1][j], P[lv][i]));
        for (i = 0; i < (1<<n); ++i)
        {
            for (nv = j = 0; j < n; ++j)
                if (i&(1<<j)) V[nv++] = j;
            for (v = V; v != V+nv; ++v)
            {
                if (A[i][*v] == INF) continue;
                for (k = 0; k < n; ++k)
                {
                    if (i&(1<<k)) continue;
                    A[i|(1<<k)][k] = min(A[i|(1<<k)][k], A[i][*v]+D[*v][k]);
                }
            }
        }

        memset(bst[lv], 0x3f, sizeof(bst[0]));
        for (i = 0; i < n; ++i)
            bst[lv][i] = A[(1<<n)-1][i];
        
        printf("%d\n", *min_element(bst[lv], bst[lv]+n));
    }

    return 0;
}