Cod sursa(job #886985)

Utilizator roots4Irimia Alexandru Gabriel roots4 Data 23 februarie 2013 14:24:11
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 kb
#include<fstream>
#include<set>
#include<vector>


using namespace std;

#define max_k 16
#define max_n 2010
#define inf 2000000000

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

set< pair <int,int> >S;

int n,m,k,C[max_k],a,b,i,j,dist[max_k+2][max_n];
int D[max_k][1<<max_k];
struct nd{
	int x , c;
};

vector<nd>G[max_n];

void read(){
	
	nd nod;
	
	f>>n>>m;
	
	f>>k;
	
	for(int i=0;i<k;i++)
		f>>C[i];
	
	for(int i=1;i<=m;i++){
		f>>a>>b>>nod.c;
		nod.x=b;
		G[a].push_back(nod);
		nod.x=a;
		G[b].push_back(nod);
	}
	
}


void dijkstra(int x , int dist[]){
	int nod1;
	
	S.clear();
	
	for (i=1;i<=n;i++)
		dist[i] = inf;
	dist[x] = 0;

	for (i=1;i<=n;++i)
		S.insert(make_pair(dist[i],i));
	for (i=1;i<n;++i)
	{
		pair<int , int> f = *S.begin();
		S.erase(S.begin());
		int nod = f.second;
		if (dist[nod] < f.first)  continue;
		for (j=0;j<G[nod].size();j++)
			if (dist[nod1 = G[nod][j].x] > dist[nod] + G[nod][j].c)
			{
				dist[nod1] = dist[nod] + G[nod][j].c;
				S.insert(make_pair(dist[nod1], nod1));
			}
	}
	
}

int power(int x){
	
	for(int j=0;j<k;j++){
		if(x==(1<<j))
			return j;
	}
	return -1;
}

int minim(int a , int b){
	if(a<b)
		return a;
	return b;	
}

int include(int x , int y){
	
	return ( (x&(1<<y))!=0 );
	
}

void print(){
	
	int minim1=inf;
	
	for(int i=0;i<k;i++)
		minim1=minim(minim1 , D[i][(1<<k)-1]+dist[i+2][n] );

	g<<minim1;
}

int main(){
	
	int sub,x,q;
	
	read();
	
	dijkstra(1,dist[1]);
	
	for(i=0;i<k;i++)
		dijkstra(C[i],dist[i+2]);
	
	i=1;
	
	while(i<(1<<k)){
		if((x=power(i))>=0)
			D[x][i]=dist[1][C[x]];
		else{
			for(j=0;j<k;j++){
				D[j][i]=inf;
				if(include(i,j)){
					for(q=0;q<k;q++){
						
						if(q!=j && include(i,q))
							D[j][i]=minim(D[j][i] , D[q][i-(1<<j)] + dist[q+2][C[j]]);
						
					}
				}
			}
			
		}
		i++;
	}
	
	print();
	
	return 0;
}