Cod sursa(job #634754)

Utilizator laurionLaurentiu Ion laurion Data 17 noiembrie 2011 00:13:38
Problema Bibel Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.83 kb
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;

struct point
{
    int x,y;
};

vector<point> v,last;
vector<int> last_dist;

//int cost[17][17];
int dp[1<<17][17];//
inline int dist(const point& a, const point& b)
{
	return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);//patratul distantei -> no sqrt() needed
}
inline int solve()
{
    memset(dp, 0x7f, sizeof(dp));

    for(int i=0;i<last.size();++i)
        for(int j=0;j<v.size();++j)
            dp[1<<j][j]=min(dp[1<<j][j],last_dist[i]+dist(last[i],v[j]));//initializare

//    //preprocesare:
//    for(int i=0;i<last.size();++i)
//        for(int j=0;j<v.size();++j)
//            cost[i][j]=dist(v[i],v[j]);

    for(int i=0,_stop=1<<v.size();i< _stop; ++i)
    {
        for(int j=0;j<v.size();++j)
        {
            if(i&(1<<j))
            {
                for(int k=0;k<v.size();++k)
                    if((i&(1<<k))==0)
                        dp[i^(1<<k)][k]=min(dp[i^(1<<k)][k],dp[i][j]+dist(v[j],v[k]));//ciclu hamiltonian
            }
        }
    }
    int ret=0x7fffffff;
    last_dist.clear();
    for(int i=0;i<v.size();++i)
    {
        last_dist.push_back(dp[(1<<v.size())-1][i]);
        ret=min(ret,last_dist[i]);
    }
    v.swap(last);
    v.clear();
    return ret;
}

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

    last.push_back((point){0, 0});
    last_dist.push_back(0);
	while (true)
	{
		int op;
		cin>>op;

		switch (op)
		{
		case 0:
            {
				int x, y;
				cin>>x>>y;

				v.push_back((point){x, y});
				break;
            }

		case 1:
            {
                cout<<solve()<<'\n';
				break;
			}

		case 2:
            {
				return 0;
			}
		}
	}

	return 0;
}