Cod sursa(job #3239724)

Utilizator AlexPlesescuAlexPlesescu AlexPlesescu Data 7 august 2024 13:45:49
Problema Bibel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.68 kb
#include <iostream>

#define NMAX 19
#define DOIN ((1 << 17) + 3)
#define INF ((1 << 30) - 1)

using namespace std;

typedef long long ll;

struct pct {
    int x, y;
} a[NMAX], lasta[NMAX];

int n, lastn;
ll dp[DOIN][NMAX], lastlvl[NMAX];

ll dist(const pct A, const pct B) {
    return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
}

ll calc() {
    for(int i = 0; i < lastn; ++i)
        lastlvl[i] = dp[(1 << lastn) - 1][i];

    for(int i = 0; i <= (1 << n); ++i)
        for(int j = 0; j <= n; ++j)
            dp[i][j] = INF;

    for(int i = 0; i < lastn; ++i)
        for(int j = 0; j < n; ++j)
            dp[1 << j][j] = min(dp[1 << j][j], lastlvl[i] + dist(lasta[i], a[j]));

    for(int mask = 1; mask < (1 << n); ++mask) {
        for(int i = 0; i < n; ++i) {
            if(mask & (1 << i)) {
                for(int j = 0; j < n; ++j)
                    if((i != j) && (mask & (1 << j))) {
                        dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + dist(a[i], a[j]));
                    }
            }
        }
    }
    ll ans = INF;
    for(int i = 0; i < n; ++i)
        ans = min(ans, dp[(1 << n) - 1][i]);
    return ans;
}

int main()
{
    freopen("bibel.in", "r", stdin);
    freopen("bibel.out", "w", stdout);
    int op;
    lasta[(lastn = 1) - 1] = {0, 0};
    while(scanf("%d", &op) != -1) {
        if(op == 1) {
            printf("%d\n", calc());
            lastn = n;
            for(int i = 0; i < n; ++i)
                lasta[i] = a[i];
            n = 0;
        } else if(op == 0) {
            scanf("%d%d", &a[n].x, &a[n].y);
            ++n;
        }
    }
    return 0;
}