Cod sursa(job #1456563)

Utilizator DrumeaVDrumea Vasile DrumeaV Data 1 iulie 2015 11:05:56
Problema Bibel Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <utility>
#include <algorithm>
#include <fstream>
#include <string.h>
#define mp make_pair
#define st first
#define nd second

using namespace std;

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

const int INF = 0x3f3f3f3f;

int Path[1 << 17][17],N[2],T[18];
pair< int,int > B[2][18];

inline int Dst(pair< int,int > A,pair< int,int > B)
{
    return (A.st - B.st) * (A.st - B.st) + (A.nd - B.nd) * (A.nd - B.nd);
}

inline int Count(int i)
{
    int Nr = 0;
    while(i)
        Nr++,i &= i - 1;

    return Nr;
}

int main()
{
    int Op,lvl = 0;

    N[1] = 1;

    do
    {
        do
        {
            fin >> Op;
            if (Op == 0)
            {
                N[lvl]++;
                fin >> B[lvl][N[lvl]].st >> B[lvl][N[lvl]].nd;
            }
        }while(Op == 0);

        if (Op == 1)
        {
            for (int i = 1;i <= N[lvl];i++)
            {
                Path[1 << (i - 1)][i] = INF;
                for (int j = 1;j <= N[lvl ^ 1];j++)
                    Path[1 << (i - 1)][i] = min(Path[1 << (i - 1)][i],T[j] + Dst(B[lvl][i],B[lvl ^ 1][j]));
            }

            for (int i = 1;i < (1 << N[lvl]);i++)
               if (Count(i) > 1)
                for (int j = 1;j <= N[lvl];j++)
                {
                    Path[i][j] = INF;
                    if (i & (1 << (j - 1)))
                     for (int k = 1;k <= N[lvl];k++)
                      if (i & (1 << (k - 1)) && j != k)
                       Path[i][j] = min(Path[i][j],Path[i ^ (1 << (j - 1))][k] + Dst(B[lvl][j],B[lvl][k]));
                }

            int Sol = INF;

            for (int i = 1;i <= N[lvl];i++)
                Sol = min(Sol,Path[(1 << N[lvl]) - 1][i]),
                T[i] = Path[(1 << N[lvl]) - 1][i];

            lvl ^= 1;
            N[lvl] = 0;


            fout << Sol << "\n";
        }
    }while(Op != 2);
    return 0;
}