Cod sursa(job #581183)

Utilizator loginLogin Iustin Anca login Data 13 aprilie 2011 21:27:40
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.75 kb
# include <fstream>
# include <iostream>
# include <vector>
# include <set>
# define INF 2000000000
# define DIM 2048
# define MAXK 20
# define pb push_back
# define mp make_pair
# define fs first
# define sc second
# define min(a,b) (a<b?a:b)
using namespace std;
int n, m, K, dd[MAXK][MAXK], vk[MAXK], w[DIM], v[DIM], d[DIM], bst[10*DIM][MAXK], sol=INF;
vector< pair<int,int> >G[DIM];
set< pair<int,int> >S;

void read ()
{
	ifstream fin ("ubuntzei.in");
	fin>>n>>m>>K;
	for(int i=1;i<=K;++i)
	{
		fin>>vk[i];
		w[vk[i]]=i;
	}
	w[n]=K+1;
	int x, y, z;
	for(int i=1;i<=m;++i)
	{
		fin>>x>>y>>z;
		G[x].pb(mp(y, z));
		G[y].pb(mp(x, z));
	}
}

void f (int poz)
{
	for(int i=1;i<=n;++i)
		d[i]=INF, v[i]=0;
	S.insert(mp(0,vk[poz]));
	d[vk[poz]]=0;
	int k, dst;
	while (S.size())
	{
		k=(*S.begin()).sc;dst=(*S.begin()).fs;
		S.erase(S.begin());
		if (!v[k])
		{
			v[k]=1;
			if (w[k])dd[poz][w[k]]=dst;
			for(vector< pair<int,int> >::iterator I=G[k].begin();I!=G[k].end();++I)
				if (!v[I->fs] && d[k]+I->sc<d[I->fs])
				{
					d[I->fs]=d[k]+I->sc;
					S.insert(mp(d[I->fs], I->fs));
				}
		}
	}
}
	
void distante ()
{
	vk[0]=1;
	for(int i=0;i<=K;++i)
		f(i);
}

void dinamo ()
{
	for(int i=1;i<=K;++i)
		bst[1<<(i-1)][i-1]=dd[0][i];
	for(int i=1;i<(1<<K);++i)
		for(int j=0;j<K;++j)
			if (i&(1<<j))
				for(int k=0;k<K;++k)
					if (!(i&(1<<k)))
					{
						if (bst[i|(1<<k)][k]==0)bst[i|(1<<k)][k]=bst[i][j]+dd[j+1][k+1];
						else bst[i|(1<<k)][k]=min(bst[i|(1<<k)][k],bst[i][j]+dd[j+1][k+1]);
					}
	int i=(1<<K)-1;
	for(int j=0;j<K;++j)
		sol=min(sol,bst[i][j]+dd[j+1][K+1]);
}

int main()
{
	read ();
	distante ();
	ofstream fout ("ubuntzei.out");
	if (K==0)
		fout<<dd[0][1];
	else if (K==1)
		fout<<dd[0][1]+dd[1][2];
	else
	{
		dinamo ();
		fout<<sol;
	}
	return 0;
}