Cod sursa(job #2305442)

Utilizator alexge50alexX AleX alexge50 Data 20 decembrie 2018 11:51:07
Problema Bibel Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <fstream>
#include <utility>
#include <numeric>
#include <limits>
#include <vector>
#include <array>

const int MAX_N = 17;
const int INF = std::numeric_limits<int>::max();

using Position = std::pair<int, int>;
template<typename T, size_t ROWS, size_t COLUMNS>
using Matrix = std::array<std::array<T, COLUMNS>, ROWS>;

//Matrix <int, (1 << MAX_N), MAX_N> dp;
int dp[1 << MAX_N][MAX_N];


int distance(const Position &a, const Position &b)
{
    int d1 = (a.first - b.first);
    int d2 = (a.second - b.second);

    return d1 * d1 + d2 * d2;
}

int main()
{
    std::ifstream fin("bibel.in");
    int t;

    std::vector<std::pair<int, Position>> oldCosts;
    std::vector<std::pair<int, int>> points;

    std::ofstream fout("bibel.out");
    oldCosts.push_back({0, {0, 0}});
    while(fin >> t, t != 2)
    {
        if(t == 0)
        {
            int x, y;
            fin >> x >> y;

            points.emplace_back(x, y);
        }
        else
        {
            int n = static_cast<int>(points.size());

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

            for(int i = 0; i < n; i++)
            {
                auto point = points[i];
                dp[1 << i][i] = std::accumulate(oldCosts.begin(), oldCosts.end(), INF, [&point](
                        int cost,
                        const std::pair<int, Position > &p){
                    return std::min(cost, p.first + distance(p.second, point));
                });
            }

            for(int i = 1; i < (1 << n); i ++)
            {
                for(int j = 0; j < n; j++)
                    for(int k = 0; k < n; k++)
                        if(((1 << k) & i) != 0 && k != j)
                            dp[i][j] = std::min(dp[i][j], dp[i ^ (1 << j)][k] + distance(points[k], points[j]));
            }


            points.clear();
            oldCosts.clear();
            int r = INF;

            for(int i = 0; i < n; i++)
            {
                r = std::min(r, dp[(1 << n) - 1][i]);
                oldCosts.emplace_back(dp[(1 << n) - 1][i], points[i]);
            }

            fout << r << "\n";

        }
    }

    return 0;
}