Cod sursa(job #701859)

Utilizator mlupseLupse-Turpan Mircea mlupse Data 1 martie 2012 18:10:25
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <fstream>
#include <vector>
#define NMAx 2012
#define KMAx 18
#define CMAx 262150
#define pb push_back
#define mkp make_pair
#define ff first
#define ss second
#define oo (1<<30)
#define left(i) (2*i)
#define right(i) (2*i+1)
#define father(i) (i/2)
#define cmp(a,b) (dist[heap[a]]<dist[heap[b]])
using namespace std;
vector <pair <int,int> > G[NMAx],G2[KMAx];
int n,k,S,D,sol,subset[KMAx];
int vf,heap[NMAx],loc[NMAx],dist[NMAx],A[CMAx][KMAx];

int hamilton(int config,int last) {
	if(!A[config][last]) {
		int fiu,p,o;
		A[config][last]=oo;
		for(fiu=0;fiu<G2[last].size();fiu++)
			if(config&(1<<G2[last][fiu].ff))
				if( G2[last][fiu].ff!=S || config==((1<<last)+(1<<S)) ) {
					p=G2[last][fiu].ff;
					o=G2[last][fiu].ss;
					A[config][last]=min(A[config][last],hamilton(config^(1<<last),p)+o);
					}
		}
	return A[config][last];
}
void up(int nod) {
	
	while(nod>1&&cmp(nod,father(nod))) {
		swap(heap[nod],heap[father(nod)]);
		swap(loc[heap[nod]],loc[heap[father(nod)]]);
		nod=father(nod);
		}
	
}
void down(int nod) {
	
	int son;
	do {
		son=0;
		if(left(nod)<=vf) {
			son=left(nod);
			if(right(nod)<=vf&&cmp(right(nod),left(nod)))
				son=right(nod);
			if(cmp(nod,son))
				son=0;
			}
		if(son) {
			swap(heap[nod],heap[son]);
			swap(loc[heap[nod]],loc[heap[son]]);
			nod=son;
			}
	}while(son);
	
}
void dijkstra(int S) {
	
	int i,nod,vecin;
	
	for(i=1;i<=n;i++)
		loc[i]=0;
	heap[1]=S;
	loc[S]=1;
	dist[S]=0;
	vf=1;
	
	while(vf) {
		
		nod=heap[1];
		heap[1]=heap[vf--];
		loc[heap[1]]=1;
		down(1);
		
		for(i=0;i<G[nod].size();i++) {
			vecin=G[nod][i].ff;
			if(!loc[vecin]) {
				heap[++vf]=vecin;
				loc[vecin]=vf;
				dist[vecin]=dist[nod]+G[nod][i].ss;
				up(loc[vecin]);
				}
			else
			if(dist[vecin]>dist[nod]+G[nod][i].ss) {
				dist[vecin]=dist[nod]+G[nod][i].ss;
				up(loc[vecin]);
				}
			}
		}

}
void constr() {
	
	int i,j;
	
	S=k+1;
	D=k+2;
	
	// De la S -> fiecare subset
	dijkstra(1);
	for(i=1;i<=k;i++)
		G2[i].pb(mkp(S,dist[subset[i]]));
	
	if(k) {
		// De la fiecare subset -> fiecare subset
		for(i=1;i<=k;i++) {
			dijkstra(subset[i]);
			for(j=1;j<=k;j++)
				if(j!=i)
					G2[j].pb(mkp(i,dist[subset[j]]));
				
			// De la ficare subset -> la D
			G2[D].pb(mkp(i,dist[n]));
			}
		
		A[(1<<S)][S]=1;
		sol=hamilton((1<<(k+3))-2,D)-1;
		}
	else
		sol=dist[n];

}
void citire() {
	
	int i,m,x,y,cost;
	ifstream in("ubuntzei.in");
	in>>n>>m>>k;
	
	for(i=1;i<=k;i++)
		in>>subset[i];
	for(i=1;i<=m;i++) {
		in>>x>>y>>cost;
		G[x].pb(mkp(y,cost));
		G[y].pb(mkp(x,cost));
		}
	in.close();
	
}
void afis() {
	
	ofstream out("ubuntzei.out");
	out<<sol<<'\n';
	out.close();

}
int main() {
	
	citire();
	constr();
	afis();
	
	return 0;
}