Cod sursa(job #1367973)

Utilizator AeroHHorea Stefan AeroH Data 2 martie 2015 12:20:54
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <fstream>
#include <vector>

using namespace std;

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
#define x first
#define y second

const int MAX_N = 17;
const int MAX_L = (1 << 17);
const int INF = 0x3f3f3f3f;

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

int C[MAX_L][MAX_N];

vector <pair<int, int> > V, Ant;
vector <int> Cant;

inline int dist(pair<int, int> a, pair<int, int> b)
{
    return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}

void solve()
{
    int D[MAX_N][MAX_N],
    N = V.size(),
    M = (1 << N);

    for(int i = 0; i < N; ++i)
        for(int j = 0; j < N; ++j)
            D[i][j] = dist(V[i], V[j]);

    for(int i = 0; i < M; ++i)
        for(int j = 0; j < N; ++j)
            C[i][j] = INF;

    for(int i = 0; i < N; ++i)
        for(size_t j = 0; j < Ant.size(); ++j)
            C[(1 << i)][i] = min(C[(1 << i)][i], Cant[j] + dist(V[i], Ant[j]));


    for(int i = 1; i < M; ++i)
        for(int j = 0; j < N; ++j)
            if(i & (1 << j))
                for(int k = 0; k < N; ++k)
                    if(i & (1 << k))
                        C[i][j] = min(C[i][j], C[i ^ (1 << j)][k] + D[k][j]);

    int Sol = INF;

    Ant.clear();
    Cant.clear();
    for(int i = 0; i < N; ++i)
    {
        Sol = min(Sol, C[M-1][i]);

        Ant.push_back(V[i]);
        Cant.push_back(C[M-1][i]);
    }
    V.clear();
    fout << Sol << "\n";
}

int main()
{
    Ant.push_back(make_pair(0, 0));
    Cant.push_back(0);

    int p;
    for(fin >> p; p != 2; fin >> p)
    {
        if(p == 1) solve();
        else
        {
            int a, b;
            fin >> a >> b;
            V.push_back(make_pair(a, b));
        }
    }
}