Cod sursa(job #3001230)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 13 martie 2023 13:25:49
Problema Bibel Scor 100
Compilator cpp-64 Status done
Runda simusimumeu Marime 2.52 kb
#include <bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC target ("popcnt")

using namespace std;

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

const int MAX_N = 17;
int type, n, m;
struct PCT{
    int x, y;
} crt[MAX_N + 5], prv[MAX_N + 5];

static inline long long dist(const PCT &p1, const PCT &p2){
    return (long long)(p1.x-p2.x) * (p1.x-p2.x) + (long long)(p1.y-p2.y) * (p1.y-p2.y);
}

long long sol, dp[MAX_N + 5][(1 << 17) + 5], finish[MAX_N + 5];
int masks[MAX_N + 5][(1 << 17) + 5];

int main(){
    ios_base::sync_with_stdio(false);
    fin.tie(nullptr), fout.tie(nullptr);

    m = 1;
    prv[1] = PCT{0, 0};
    finish[1] = 0;

    while(true){
        fin>>type;
        if(type == 0){
            n++;
            fin>>crt[n].x>>crt[n].y;
        }else if(type == 1){
            for(int mask=0; mask < (1 << n); mask++)
                masks[__builtin_popcount(mask)][++masks[__builtin_popcount(mask)][0]] = mask;

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

            for(int i=1; i<=m; i++)
                for(int j=1; j<=n; j++)
                    dp[j][(1<<(j-1))] = min(
                        dp[j][(1<<(j-1))],
                        finish[i] + dist(prv[i], crt[j])
                    );

            for(int bit=1; bit<=n; bit++)
                for(int mi=1, mask; mi<=masks[bit][0]; mi++){
                    mask = masks[bit][mi];
                    for(int i=1; i<=n; i++)
                        for(int j=1; j<=n; j++)
                            if(i != j && (mask & (1<<(i-1))) && (mask & (1<<(j-1))))
                                ///merg de la i la j
                                dp[j][mask] = min(
                                    dp[j][mask],
                                    dp[i][(mask ^ (1<<(j-1)))] + dist(crt[i], crt[j])
                                );
                }

            ///get solution & transfer
            sol = LONG_MAX;
            for(int i=1; i<=n; i++){
                sol = min(sol, dp[i][(1<<n)-1]);
                finish[i] = dp[i][(1<<n)-1];
                prv[i] = crt[i];
            }
            m = n;
            fout<<sol<<"\n";

            ///reset
            for(int bit=0; bit<=n; bit++)
                masks[bit][0] = 0;
            n = 0;
        }else if(type == 2){
            break;
        }
    }
    return 0;
}
/**
0 0 2
0 2 0
0 2 2
1
0 4 4
0 6 6
0 8 8
1
2
**/