Cod sursa(job #778621)

Utilizator danalex97Dan H Alexandru danalex97 Data 15 august 2012 11:22:14
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.81 kb
#include <fstream>
#include <vector>
using namespace std;

const int Nmax = 20;
const int oo = 1<<30;

struct Point{int x;int y;};

vector< Point > Pnct;
int Cost[Nmax][Nmax],N=2;
int D[1<<Nmax][Nmax]; 
int Best[Nmax],Nbr;
Point Sir[Nmax];

ifstream F("bibel.in");
ofstream G("bibel.out");
	
inline int dist(Point i,Point j)
{	return (i.x-j.x)*(i.x-j.x) + (i.y-j.y)*(i.y-j.y) ;  }

void Solve()
{
	for ( vector<Point>::iterator i=Pnct.begin();i!=Pnct.end();++i )
	{
		Best[i-Pnct.begin()]=oo;
		for (int j=1;j<=Nbr;++j)
			Best[i-Pnct.begin()]=min( Best[i-Pnct.begin()] , dist(Sir[j],*i) + D[(1<<(N-1))-1][j] );
	}
	
	for ( vector<Point>::iterator i=Pnct.begin();i!=Pnct.end();++i )
		for ( vector<Point>::iterator j=Pnct.begin();j!=Pnct.end();++j )
			Cost[i-Pnct.begin()][j-Pnct.begin()] = dist(*i,*j);
	
	N=Pnct.size();	
	int Stop=1<<(N-1);
	
	for (int i=1;i<Stop;++i)
	{
		for (int j=1,cj=1;j<=i;j<<=1,++cj)
			if ( j & i )
			{
				D[i][cj]=oo;
				if ( (i ^ j) == 0 )
				{
					D[i][cj] = Best[cj];
					continue;
				}
				for (int jj=1,cjj=1;jj <= (i ^ j);jj<<=1,++cjj)
					if ( (i ^ j) & jj )
						D[i][cj]=min( D[i][cj] , D[i ^ j][cjj] + Cost[cjj][cj] );
			}
	}
	
	int Rez=oo;
	Nbr=0;
	
	for (int j=1,cj=1;j<Stop;j<<=1,++cj)
	{
		Rez=min( Rez,D[Stop-1][cj] );
		Sir[ ++Nbr ]= Pnct[cj] ;
	}
	
	G<<Rez<<'\n';
}

int main()
{
	Point P;P.x=0,P.y=0;
	Pnct.push_back( P );
	
	Sir[++Nbr]=P;
	
	while ( 1 )
	{
		int z,x,y;
		F>>z;
		switch( z )
		{
			case 0:
				{
					F>>x>>y;
					Point P;P.x=x,P.y=y;
					Pnct.push_back( P );
					break;
				}
			case 1:
				{
					Solve();
					
					while ( Pnct.size() ) 
						Pnct.pop_back();
					Point P;P.x=0,P.y=0;
					Pnct.push_back( P );
					
					break;
				}
			case 2:
				return 0;
		}
	}
}