Cod sursa(job #1005840)

Utilizator teoionescuIonescu Teodor teoionescu Data 5 octombrie 2013 22:07:40
Problema Ubuntzei Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include<fstream>
#include<vector>
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int Nmax = 2005;
const int Mmax = 10005;
const int Powmax = 1<<15;
const int INF = 1<<30;
int N,M,K;
struct path{
	int dest,cost;
};
vector<path> G[Nmax];
struct heap_item{
	int val,xx,id;
} H[Nmax+Mmax]; int L;
int D[Nmax][Powmax],v[Nmax],dN;
void swap(int a,int b){
	heap_item aux;
	aux=H[a];
	H[a]=H[b];
	H[b]=aux;
}
bool compare(int a, int b){
	return (H[a].val > H[b].val);
}
void upheap(int i){
	if( i/2>0 && compare(i/2,i) ){
		swap(i/2,i);
		upheap(i/2);
	}
}
void downheap(int i){
	if( 2*i+1<=L && compare(i,2*i+1) ){
		swap(2*i+1,i);
		downheap(2*i+1);
	}
	else if( 2*i<=L && compare(i,2*i) ){
		swap(2*i,i);
		downheap(2*i);
	}
}
heap_item First(){
	heap_item R=H[1];
	swap(1,L);
	L--;
	downheap(1);
	return R;
}
void Push(heap_item x){
	H[++L]=x;
	upheap(L);
}
void Proc(int x,int y,int val,int cost,int ID){
	heap_item p;
	int ok=1;
	for(int i=1;i<=K;i++){
		if(v[i]==y && !( ID&(1<<(i-1)) )){
			if(val+cost<D[y][ID+(1<<(i-1))]){
			    ok=0;
				D[y][ID+(1<<(i-1))]=val+cost;
				p.val=D[y][ID+(1<<(i-1))];
				p.xx=y;
				p.id=ID+(1<<(i-1));
				//out<<x<<"to"<<y<<" ID"<<ID<<" + "<<(1<<(i-1))<<"      "<<D[y][ID+(1<<(i-1))]<<'\n';
				Push(p);
			}
		}
	}
    if(ok && val+cost<D[y][ID]){
        D[y][ID]=val+cost;
        p.val=D[y][ID];
        p.xx=y;
        p.id=ID;
        //out<<x<<"to"<<y<<' '<<ID<<"           "<<D[y][ID]<<'\n';
        Push(p);
    }
}
int main(){
	int i,j,x,y,c;
	in>>N>>M>>K;
	for(i=1;i<=K;i++) in>>v[i];
	for(i=1;i<=M;i++){
		in>>x>>y>>c;
		path w;
		w.cost=c;
		w.dest=y;
		G[x].push_back(w);
		w.dest=x;
		G[y].push_back(w);
	}
	dN=(1<<K)-1;
	for(i=1;i<=N;i++){
		for(j=0;j<=dN;j++){
			D[i][j]=INF;
		}
	}
	D[1][0]=0;
	heap_item start;
	start.val=0;
	start.xx=1;
	start.id=0;
	Push(start);
	while(L){
		heap_item p=First();
		//p.val p.xx p.id
		for(vector<path>::iterator it=G[p.xx].begin();it!=G[p.xx].end();++it){
			//it->dest it->cost
			Proc(p.xx,it->dest,p.val,it->cost,p.id);
		}
	}
	out<<D[N][dN];
	return 0;
}