Cod sursa(job #677383)

Utilizator RengelBotocan Bogdan Rengel Data 10 februarie 2012 08:42:01
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
/*
	Dijkstra din toate nodurile
	K[i] + nodul 1.
*/

#include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
#define inf  2005
#define inf2 100000005

int n,m,k;
int K[inf];
int S[inf], D[inf];
int B[20][inf];
int A[inf][inf];
int N;
int st[20];
int best,sum;
int F[20];

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]);
	
	for(int i=1;i<=n;i++)
		for(int j=1; j<=m; j++)
			A[i][j]=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 dijkstra(int start){
	
	memset(S,0,4*(n+1));
	
	/*	Initializare Dijkstra	*/
	
	S[start]++;					//	Selectez nodul start;
	
	for(int i=1; i<=n; i++){	//	Copiez linia A[start] in D
		D[i]=A[start][i];
	}
	
	/*	Dijkstra	*/
	
	for(int i=1; i<=n-2; i++){
		
		//	Caut minimul din D[i] cu !S[i]
		int min = inf;
		int poz;
		for(int j=1; j<=n;	j++)
			if(D[j] < min && !S[j]){
				min=D[j];
				poz=j;
			}
		
		//	Selectez nodul poz
		S[poz]++;
		
		//	Caut prin nodul poz drumuri mai scurte catre toate
		//	nodurile neselectate pana acum
		
		for(int j=1; j<=n; j++)
			if(min + A[poz][j] < D[j])
				D[j]=min + A[poz][j];
		
		
	}
	
	++N;
	int j=0;
	for(int i=1;i<=n;i++)
		if(std::binary_search(K+1,K+k+1,i) || i==1 || i==n)
			B[N][++j]=D[i];
}

void back(int k){
	
	for(int i=2;i<=N;i++){
		if(!F[i]){						//	Daca nu am mai trecut inca o data prin nodul i
			st[k] = i;					//	Adaug un element la drum;
			sum += B[st[k-1]][st[k]];	//	Adaug costul la suma;
			F[i] ++;						//	Marchez ca am trecut prin nodul i
			if(k==N){
				if(sum + B[st[N]][k+1] < best) best = sum + B[st[N]][k+1];
			}
			else if(sum <= best)
				back(k+1);
			sum -= B[st[k-1]][st[k]];
			F[i] --;
		}
	}
	
}

int main(){
	
	read();
	
	std::sort(K+1,K+1+k);
	dijkstra(1);
	
	for(int i=1;i<=k;i++)
		dijkstra(K[i]);
	
	freopen("ubuntzei.out","w",stdout);
	if(!k) printf("%d",B[1][2]);
	else{
	
		/*	Initializare back	*/
		
		st[1] = 1;
		F[1] ++;
		best = 	INT_MAX;
		//back(2);
		
		printf("%d",best);
		
	}
	
	fclose(stdout);
	
	return 0;
	
}