Cod sursa(job #1997090)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 3 iulie 2017 12:48:34
Problema Bibel Scor 100
Compilator cpp Status done
Runda Simulare 18b Marime 2 kb
#include <fstream>

using namespace std;

ifstream fin ("bibel.in"); ofstream fout ("bibel.out");

const int nmax = 17;
const unsigned int inf = (1LL << 31) - 1 + (1LL << 31);

pair<int, int> v[nmax + 1], w[nmax + 1];
unsigned int l[nmax + 2][nmax + 2];
unsigned int d[(1 << nmax)][ nmax ];

inline int p2 (int x) {
    return x * x;
}

unsigned int dist (pair<int, int> x, pair<int, int > y) {
    return p2(x.first - y.first) + p2(x.second - y.second);
}

int main() {
    int tip, test = 0;

    int ant = 0;

    fin >> tip;
    while (tip != 2) {
        int n = 0;

        while (tip != 1) {
            fin >> v[ n ].first >> v[ n ].second;
            ++ n;
            fin >> tip;
        }
        ++ test;

        for (int i = 0; i < n; ++ i) {
            for (int j = 0; j < n; ++ j) {
                l[ i ][ j ] = dist(v[ i ], v[ j ]);
            }

            if (test == 1) l[n + 1][ i ] = dist(make_pair(0, 0), v[ i ]);
            else           l[n + 1][ i ] = inf;

            for (int j = 0; j < ant; ++ j) {
                l[n + 1][ i ] = min(l[n + 1][ i ], d[(1 << ant) - 1][ j ] + dist(w[ j ], v[ i ]));
            }
        }
        for (int i = 0; i < n; ++ i) {
            d[(1 << i)][ i ] = l[n + 1][ i ];
        }

        for (int i = 1; i < (1 << n); ++ i) {
            for (int j = 0; j < n; ++ j) {
                if ((i & (1 << j)) == 0) continue;

                int stn = i - (1 << j);
                if (stn == 0) continue;

                d[ i ][ j ] = inf;
                for (int x = 0; x < n; ++ x) {
                    if ((stn & (1 << x)) == 0) continue;

                    d[ i ][ j ] = min(d[ i ][ j ], d[ stn ][ x ] + l[ x ][ j ]);
                }
            }
        }

        unsigned int ans = inf;
        for (int i = 0; i < n; ++ i) {
            ans = min(ans, d[(1 << n) - 1][ i ]);
        }
        fout << ans << "\n";

        ant = n;
        for (int i = 0; i < n; ++ i) w[ i ] = v[ i ];

        fin >> tip;
    }
    fin.close();
    fout.close();
    return 0;
}