Cod sursa(job #612998)

Utilizator paul_gabryelPaul Buda paul_gabryel Data 14 septembrie 2011 13:26:43
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include <fstream>
#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

#define M 2048
#define N 20
#define pb push_back
#define mp make_pair
#define f first
#define s second

int n,m,K,dd[N][N],vk[N],w[M],v[M],d[M],bst[20*M][N],sol=INT_MAX;
vector<pair<int,int> > g[M];
set<pair<int,int> >q;

void read ()
{
	ifstream fin ("ubuntzei.in");
	fin>>n>>m>>K;
	for(int i=1;i<=K;++i)
	{
		fin>>vk[i];
		w[vk[i]]=i;
	}
	vk[0]=1;
	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 dist (int pz)
{
	for(int i=1;i<=n;++i){
		d[i]=INT_MAX;
		v[i]=0;
	}
	q.insert(mp(0,vk[pz]));
	d[vk[pz]]=0;
	for(int k,dst;q.size();)
	{
		k=q.begin()->s;
		dst=q.begin()->f;
		q.erase(q.begin());
		if(!v[k])
		{
			v[k]=1;
			if(w[k])
                dd[pz][w[k]]=dst;
			for(vector<pair<int,int> >::iterator it=g[k].begin();it<g[k].end();++it)
				if(!v[it->f]&&d[k]+it->s<d[it->f])
				{
					d[it->f]=d[k]+it->s;
					q.insert(mp(d[it->f],it->f));
				}
		}
	}
}

void dinam ()
{
	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)
		if(sol>bst[i][j]+dd[j+1][K+1])
            sol=bst[i][j]+dd[j+1][K+1];
}

int main()
{
	read();
	for(int i=0;i<=K;++i)
		dist(i);
    freopen("ubuntzei.out","w",stdout);
	if(K==0)
		printf("%d",dd[0][1]);
	else
        if(K==1)
            printf("%d",dd[0][1]+dd[1][2]);
        else
        {
            dinam();
            printf("%d",sol);
        }
	return 0;
}