Cod sursa(job #3001215)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 13 martie 2023 13:02:36
Problema Bibel Scor 5
Compilator cpp-64 Status done
Runda simusimumeu Marime 2.64 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][MAX_N + 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)-1; j++)
                    dp[i][j] = LONG_MAX;

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

            for(int bit=1; bit < n; bit++)
                for(int i=1; i<=n; i++)
                    for(int j=1; j<=n; j++)
                        for(int mi=1, crt_mask, nxt_mask; mi<=masks[bit][0]; mi++){
                            crt_mask = masks[bit][mi];

                            ///merg de la i la j
                            if(dp[i][crt_mask] != LONG_MAX)
                                if((crt_mask & (1 << (i-1))) != 0 && (crt_mask & (1 << (j-1))) == 0){
                                    nxt_mask = (crt_mask | (1 << (j-1)));
                                    dp[j][nxt_mask] = min(
                                        dp[j][nxt_mask],
                                        dp[i][crt_mask] + 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];
            }
            fout<<sol<<"\n";
            m = n;
            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
**/