Cod sursa(job #690714)

Utilizator crushackPopescu Silviu crushack Data 25 februarie 2012 20:12:41
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#define NMax 2010
#define KMax 17
#define LMax (1<<KMax)
using namespace std;

const char IN[]="ubuntzei.in",OUT[]="ubuntzei.out";

int N,M,K,L,Rez;
int C[NMax] , T[NMax] , H[NMax] , Poz[NMax] , Dist[KMax][NMax];
int Din[LMax][KMax+1];
vector<pair<int,int> > ad[NMax];

bool cmp(int x,int y){
	return T[x]<T[y];
}

void change(int x,int y){
	swap(H[x],H[y]);
	swap(Poz[H[x]],Poz[H[y]]);
}

void remake(int x)
{
	int min=x,l=2*x,r=l+1;
	
	if ( l<=L && cmp(H[l],H[min]) ) min=l;
	if ( r<=L && cmp(H[r],H[min]) ) min=r;
	
	if (min!=x){
		change(min,x);
		remake(min);
	}
}

void push(int x){
	if (Poz[x]) return;
	Poz[x]=++L;H[L]=x;
	for (int i=L;i>1 && cmp(H[i],H[i>>1]) ; i>>=1) change(i,i>>1);
}

void pop(int x){
	int i;
	for (i=Poz[x];i>1;i>>=1) change(i,i>>1);
	change(1,L);H[L--]=0;Poz[x]=0;
	remake(1);
}

void ajust(int x){
	if (!Poz[x])
		push(x);
	else {
		for (int i=Poz[x];i>1 && cmp(H[i],H[i>>1]) ; i>>=1) change(i,i>>1);
		remake(Poz[x]);
	}
}

void Dijkstra(int start){
	
	int i,x;
	T[start]=0;
	push(start);
	
	while (L>0)
	{
		x=H[1];pop(x);
		for (i=0;i<(int)ad[x].size();++i) if ( T[x] + ad[x][i].second < T[ad[x][i].first] ){
			T[ad[x][i].first]=T[x] + ad[x][i].second;
			ajust(ad[x][i].first);
		}
	}
}

void solve()
{
	int mask,i,j,nod;
	memset(Din,0x3f,sizeof(Din));
	Din[1][1]=0;
	for (mask=1;mask<(1<<K);++mask)
		for (i=1;i<=K;++i)
		{
			for (j=1;j<=K;++j) 
				if (  (mask&(1<<j-1)) == 0 )
					Din[mask^(1<<j-1)][j]=min(Din[mask^(1<<j-1)][j],Din[mask][i] + Dist[i][C[j]]);
		}
}

int main()
{
	int i,x,y,c;
	freopen(IN,"r",stdin);
	scanf("%d%d%d",&N,&M,&K);
	C[1]=1;C[K+2]=N;
	for (i=1;i<=K;++i) scanf("%d",C+i+1);
	for (i=1;i<=M;++i)
		scanf("%d%d%d",&x,&y,&c),
		ad[x].push_back(make_pair(y,c)),
		ad[y].push_back(make_pair(x,c));
	fclose(stdin);
	
	K+=2;
	for (i=1;i<=K;++i)
	{
		memset(T,0x3f,sizeof(T));
		Dijkstra(C[i]);
		memcpy(Dist[i],T,sizeof(Dist[i]));
	}
	solve();
	
	freopen(OUT,"w",stdout);
	printf("%d\n",Din[(1<<K)-1][K]);
	fclose(stdout); 
	return 0;
}