Cod sursa(job #672650)

Utilizator RengelBotocan Bogdan Rengel Data 2 februarie 2012 21:14:50
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.64 kb
#include<cstdio>
#include<climits>
#include<memory>

#define inf 2005

int A[2005][2005];
int B[20][2005];
int S[2005];
int D[2005];
int F[2005];
int st[20];
int f[20];
int best=INT_MAX;
int sum;

int m,n,k,K[20];
int N;

void read(){
	
	freopen("ubuntzei.in","r",stdin);
	
	scanf("%d%d",&n,&m);
	
	scanf("%d",&k);
	
	for(int i=1;i<=k;i++){
		scanf("%d",&K[i]);
		F[K[i]]++;
	}
	F[1]=F[n]=1;
	
	for(int i=1;i<=n;i++)
		for(int j=i+1;j<=n;j++)
			A[i][j]=A[j][i]=inf;
	
	int x,y,c;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&x,&y,&c);
		A[x][y]=A[y][x]=c;
	}
	
	fclose(stdin);
	
}

void minim(int &min,int &poz){
	
	min=INT_MAX;
	for(int i=1;i<=n;i++)
		if(!S[i] && D[i]<min){
			min=D[i];
			poz=i;
		}
	
}

void dijkstra(int nod){
	
	for(int i=1;i<=n;i++)
		if(i!=nod)
			D[i]=A[nod][i];
	
	S[nod]++;
	
	int min,poz;
	for(int i=1;i<=n-1;i++){
		minim(min,poz);
		S[poz]++;
		for(int j=1;j<=n;j++)
			if(!S[j] && min+A[poz][j]<D[j])
				D[j]=min+A[poz][j];
		
	}
	
	int j=0;
	++N;
	for(int i=1;i<=n;i++)
		if(F[i])
			B[N][++j]=D[i];
	
}

void back(int k){
	
	for(int i=1;i<=N;i++)
		if(!f[i]){
			st[k]=i;
			if(sum<best){
				sum+=B[st[k-1]][st[k]];
				f[i]++;
				if(k==N){
					if(best>sum+B[st[N]][N+1])
						best=sum+B[st[N]][N+1];
				}
				else back(k+1);
				f[i]--;
				sum-=B[st[k-1]][st[k]];
			}
		}
	
}

int main(){
	
	read();
	
	dijkstra(1);
	for(int i=1;i<=k;i++){
		memset(S,0,sizeof(int)*(n+1));
		D[K[i]]=0;
		dijkstra(K[i]);
	}
	
	st[1]=1;
	f[1]=1;
	back(2);
	
	freopen("ubuntzei.out","w",stdout);
	printf("%d",best);
	
	return 0;
	
}