Cod sursa(job #885430)

Utilizator raulstoinStoin Raul raulstoin Data 21 februarie 2013 22:43:09
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.5 kb
#include<fstream>
#include<vector>
#include<algorithm>
#define NMAX 2005
using namespace std;
vector < pair<int,int> > G[NMAX],ALT[NMAX];
int n,m,k,S,D;

// pt DIJKSTRA
int d[NMAX],heap[NMAX],poz[NMAX];
#define inf (1<<30)
#define swap2(a,b) poz[heap[a]]=b
#define vec G[minim][i].first
#define cost G[minim][i].second

// pt HAMILTON
int oras[16],H[(1<<18)][18];
#define ORAS ALT[last][i].first
#define DISTANTA ALT[last][i].second

//DIJKSTRA
void up(int c)
{
	while(c>1)
	{
		if(d[heap[c/2]]>d[heap[c]])
		{
			swap2(c/2,c);
			swap2(c,c/2);
			swap(heap[c/2],heap[c]);
			c>>=1;
		}
		else
			break;
	}
}
void down(int c,int k)
{
	int jos;
	while(c<=k)
	{
		jos=c;
		if(c*2<=k)
		{
			jos<<=1;
			if(jos+1<=k && d[heap[jos+1]]<d[heap[jos]])
				jos++;
		}
		else
			break;;
		if(d[heap[c]]>d[heap[jos]])
		{
			swap2(c,jos);
			swap2(jos,c);
			swap(heap[jos],heap[c]);
			c=jos;
		}
		else
			break;
	}
}
void dijkstra(int nod)
{
	int minim,k=0;
	for(int i=0;i<=n;poz[i]=0,i++)
		d[i]=inf;
	heap[++k]=nod;
	poz[nod]=1;
	d[nod]=0;
	while(k)
	{
		minim=heap[1];
		swap(heap[1],heap[k]);
		swap2(1,1);
		k--;
		down(1,k);
		for(size_t i=0;i<G[minim].size();i++)
			if(d[vec]>d[minim]+cost)
			{
				d[vec]=d[minim]+cost;
				if(poz[vec])
					up(poz[vec]);
				else
				{
					heap[++k]=vec;
					poz[heap[k]]=k;
					up(k);
				}
			}
	}
}
//

// HAMILTON
inline int hamilton(int c,int last)
{
    if(!H[c][last])
	{
        H[c][last]=inf;
        for(size_t i=0;i<ALT[last].size();i++)
            if(c & (1<<ORAS))
                if(ORAS!=S || c==((1<<last)+(1<<S)))
                    H[c][last]=min(H[c][last],hamilton(c^(1<<last),ORAS)+DISTANTA);
	}
    return H[c][last];
}
//

void read()
{
	ifstream fin("ubuntzei.in");
	fin>>n>>m>>k;
	int x,y,z;
	for(int i=1;i<=k;i++)
		fin>>oras[i];
	for(int i=1;i<=m;i++)
	{
		fin>>x>>y>>z;
		G[x].push_back(make_pair(y,z));
		G[y].push_back(make_pair(x,z));
	}
	fin.close();
}
void solve()
{
	ofstream fout("ubuntzei.out");
	S=k+1;
	D=k+2;
	dijkstra(1);
	if(k)
	{
		for(int i=1;i<=k;i++)
			ALT[i].push_back(make_pair(S,d[oras[i]]));
		for(int i=1;i<=k;i++)
		{
			dijkstra(oras[i]);
			for(int j=1;j<=k;j++)
				if(i!=j)
					ALT[j].push_back(make_pair(i,d[oras[j]]));
			ALT[D].push_back(make_pair(i,d[n]));
		}
		H[1<<S][S]=1;
		fout<<hamilton((1<<(k+3))-2,D)-1;
	}
	else
		fout<<d[n]<<'\n';
	fout.close();
}
int main()
{
	read();
	solve();
	return 0;
}