Cod sursa(job #650740)

Utilizator darrenRares Buhai darren Data 18 decembrie 2011 20:56:02
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.54 kb
#include <cstdio>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <utility>

using namespace std;

#define x first
#define y second

const int INF = 0x3f3f3f3f;

int N[2];
pair<int, int> A[2][18];
int minC[1 << 17][17], aux[18];

inline int dist(const pair<int, int>& A, const pair<int, int>& B)
{
	return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y);
}
inline int bit(int i)
{
	int R = 0;
	while (i)
		++R, i &= i - 1;
	return R;
}

int main()
{
	ifstream fin("bibel.in");
	ofstream fout("bibel.out");
	
	N[1] = 1;
	
	int op, act = 0;
	while (true)
	{
		fin >> op;
		
		if (op == 0)
		{
			++N[act];
			fin >> A[act][N[act]].x >> A[act][N[act]].y;
		}
		else if (op == 1)
		{
			for (int i = 1; i <= N[act]; ++i)
			{
				minC[1 << (i - 1)][i] = INF;
				for (int j = 1; j <= N[!act]; ++j)
					minC[1 << (i - 1)][i] = min(minC[1 << (i - 1)][i], aux[j] + dist(A[act][i], A[!act][j]));
			}
			for (int i = 1; i < (1 << N[act]); ++i)
				if (bit(i) > 1)
					for (int j = 1; j <= N[act]; ++j)
					{
						minC[i][j] = INF;
						if (i & (1 << (j - 1)))
							for (int k = 1; k <= N[act]; ++k)
								if (j != k && (i & (1 << (k - 1))))
									minC[i][j] = min(minC[i][j], minC[i ^ (1 << (j - 1))][k] + dist(A[act][j], A[act][k]));
					}
			
			int R = INF;
			for (int i = 1; i <= N[act]; ++i)
			{
				R = min(R, minC[(1 << N[act]) - 1][i]);
				aux[i] = minC[(1 << N[act]) - 1][i];
			}
			fout << R << '\n';
			
			memset(minC, 0, sizeof(minC));
			N[!act] = 0;
			act = !act;
		}
		else if (op == 2) break;
	}
	
	fin.close();
	fout.close();
}