Cod sursa(job #389809)

Utilizator Mishu91Andrei Misarca Mishu91 Data 2 februarie 2010 11:46:19
Problema Bibel Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 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");

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 C[MAX_L][MAX_N], 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));
		}
	}
}