Cod sursa(job #2021310)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 13 septembrie 2017 10:41:03
Problema Bibel Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>

const int MAXN = 17;
const int MAXT = 200;

const int INF = (int) 1e9;

std::vector < std::pair <int, int> > pts[MAXT + 1];
int dp[MAXT + 1][MAXN];

int dp1[1 << MAXN][MAXN];

inline int dist(std::pair <int, int> a, std::pair <int, int> b) {
    return (a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second);
}

std::vector <int> bits;

char lg[(1 << MAXN) + 1];

int main() {
    FILE *fi, *fout;
    int i, t, x, y;
    fi = fopen("bibel.in" ,"r");
    fout = fopen("bibel.out" ,"w");
    for(i = 1; i <= MAXN; i++)
        lg[1 << i] = i;
    bool flag = 1;
    bool ok = 1;
    int cnt = 0;
    pts[0].push_back({0, 0});
    while(flag) {
        fscanf(fi,"%d " ,&t);
        if(t == 2)
            flag = 0;
        else if(t == 0) {
            if(ok == 1) {
                 ok = 0;
                 cnt++;
            }
            fscanf(fi,"%d %d " ,&x,&y);
            pts[cnt].push_back({x, y});
        }
        else if(t == 1) {
            ok = 1;
            for(i = 0; i < pts[cnt].size(); i++)
                dp[cnt][i] = INF;
            for(int nod = 0; nod < pts[cnt].size(); nod++) {
                dp1[1 << nod][nod] = INF;
                for(i = 0; i < pts[cnt - 1].size(); i++)
                    dp1[1 << nod][nod] = std::min(dp1[1 << nod][nod], dp[cnt - 1][i] + dist(pts[cnt][nod], pts[cnt - 1][i]));
                for(int conf = 3; conf < (1 << pts[cnt].size()); conf++) {
                    if((conf & (conf - 1)) && (conf & (1 << nod))) {
                        int cnf = conf;
                        bits.clear();
                        while(cnf > 0) {
                            int lsb = (cnf & (-cnf));
                            bits.push_back(lg[lsb]);
                            cnf -= lsb;
                        }
                        for(auto it : bits) {
                            dp1[conf][it] = INF;
                            if(it != nod)
                              for(auto it1 : bits)
                                 if(it != it1)
                                      dp1[conf][it] = std::min(dp1[conf][it], dp1[conf ^ (1 << it)][it1] + dist(pts[cnt][it], pts[cnt][it1]));
                        }
                    }
                }
                for(i = 0; i < pts[cnt].size(); i++)
                    dp[cnt][i] = std::min(dp[cnt][i], dp1[(1 << pts[cnt].size()) - 1][i]);
            }
            int ans = INF;
            for(i = 0; i < pts[cnt].size(); i++)
                ans = std::min(ans, dp[cnt][i]);
            fprintf(fout,"%d\n" ,ans);
        }
    }
    fclose(fi);
    fclose(fout);
    return 0;
}