Cod sursa(job #117349)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 21 decembrie 2007 11:09:30
Problema Bibel Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <cstdio>
#include <vector>
#include <bitset>

using namespace std;

vector< pair<int, int> > cur;
vector< vector< pair<int, int> >  > game;

#define MAXB 17

bitset< 1 << MAXB > seen[MAXB];
unsigned bst[ 1 << MAXB ][MAXB];
unsigned last[MAXB];

unsigned curDist[MAXB][MAXB];

inline unsigned sqr( int x ) { return (unsigned)x * x; }

inline unsigned dist( const pair<int, int> &a, const pair<int, int> &b )
{
	return sqr(a.first - b.first) + sqr(a.second - b.second);
}

int main()
{
	freopen("bibel.in", "rt", stdin);
	freopen("bibel.out", "wt", stdout);

	game.clear(); cur.clear();
	for (; 1; )
	{
		int type;
		scanf("%d", &type);
		if (type == 2)
			break;
		if (type == 1)
			game.push_back( cur ),
			cur.clear();

		if (type == 0)
		{
			int X, Y;
			scanf("%d %d", &X, &Y);
			cur.push_back( make_pair(X, Y) );
		}
	}

	for (size_t a = 0; a < game[0].size(); a++)
		bst[ 1 << a ][a] = dist( make_pair(0, 0), game[0][a] ),
		seen[a][ 1 << a ] = 1;

	for (size_t k = 0; k < game.size(); k++)
	{
		for (size_t a = 0; a < game[k].size(); a++)
			for (size_t b = 0; b < game[k].size(); b++)
				curDist[a][b] = dist( game[k][a], game[k][b] );

		for (int st = 1; st < (1 << game[k].size()); st++)
			for (size_t a = 0; a < game[k].size(); a++)
			{
				if (!(st & (1 << a))) continue;
				if (!seen[a][st]) continue;

				for (size_t b = 0; b < game[k].size(); b++)
				{
					if (st & (1 << b)) continue;
					unsigned val = bst[st][a] + curDist[a][b];

					if (val < bst[ st | (1 << b) ][b] || !seen[b][ st | (1 << b) ])
						bst[ st | (1 << b) ][b] = val,
						seen[b][ st | (1 << b) ] = 1;
				}
			}

		unsigned MIN = 0xffffffff;
		for (size_t a = 0; a < game[k].size(); a++)
		{
			last[a] = bst[ (1 << game[k].size()) - 1 ][a];
			if (last[a] < MIN)
				MIN = last[a];
		}
		printf("%u\n", MIN);

		for (size_t a = 0; a < game[k].size(); a++)
			seen[a].reset();
		if (k + 1 < game.size())
			for (size_t a = 0; a < game[k + 1].size(); a++)
			{
				unsigned MIN = 0xffffffff;
				for (size_t b = 0; b < game[k].size(); b++)
				{
					unsigned val = last[b] + dist( game[k][b], game[k + 1][a] );
					if (val < MIN)
						MIN = val;
				}
				bst[ (1 << a) ][a] = MIN;
				seen[a][ (1 << a) ] = 1;
			}
	}

	return 0;
}