Cod sursa(job #525757)

Utilizator mgntMarius B mgnt Data 26 ianuarie 2011 03:05:17
Problema Bibel Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.37 kb
#include <fstream>
using namespace std;

typedef long long int lli;

lli const maxc=10*1000,maxn=17,inf=maxn*(2*(maxc*maxc)+1);
struct hamiltonian_path
{

lli m,
SX[maxn],SY[maxn],V[maxn],

n,
X[maxn],Y[maxn],

W[maxn][maxn],

D[1<<maxn][maxn];

int get_minimum_weight()
{	lli x,t,s,v,y,bx,by,dx,dy,dd,b;
			
	t=(1<<n)-1;	
	for(s=0;t>=s;++s)
	{	for(x=0;n>x;++x){D[s][x]=inf;}
	}
	
	for(s=0;n>s;++s)
	{	for(t=0;m>t;++t)
		{	dx=(SX[t]-X[s]);dx*=dx;
			dy=(SY[t]-Y[s]);dy*=dy;
			dd=dx+dy+V[t];
			if(D[(1<<s)][s]>dd){D[(1<<s)][s]=dd;}
		}
	}
	
	for(s=0;n>s;++s)
	{	D[s][s]=inf;	
		for(t=s+1;n>t;++t)
		{	dx=(X[s]-X[t]);dx*=dx;
			dy=(Y[s]-Y[t]);dy*=dy;
			dd=dx+dy;
			W[s][t]=W[t][s]=dd;
		}
	}
	
	t=(1<<n)-1;
	for(s=0;t>=s;++s)
	{	for(x=0;n>x;++x)
		{	bx=(1<<x);
			if(s&bx)
			{	for(y=0;n>y;++y)
				{	by=(1<<y);
					if(0==(s&by))
					{	v=D[s][x]+W[x][y];
						if(v<D[s|by][y]){D[s|by][y]=v;}
					}
				}
			}
		}
	}
	
	b=inf;
	for(y=0;n>y;++y)
	{	if(b>D[t][y]){b=D[t][y];}	}
	
	m=n;
	for(s=0;m>s;++s)
	{	SX[s]=X[s];
		SY[s]=Y[s];
		V[s]=D[t][s];
	}
	
	return b;
}

};

hamiltonian_path H;

int main()
{	ifstream is("bibel.in");
	ofstream os("bibel.out");
	lli op,a,n=0;
	H.SX[0]=H.SY[0]=H.V[0]=0;H.m=1;
	do
	{	is>>op;
		switch(op)
		{	case 0:
				is>>H.X[n]>>H.Y[n];++n;
				break;
			case 1:
				H.n=n;a=H.get_minimum_weight();
				os<<a<<endl;n=0;
				break;
		}
	} while(2!=op);
	return 0;
}