Cod sursa(job #701733)

Utilizator andrey932Andrei andrey932 Data 1 martie 2012 17:36:56
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <bitset>
using namespace std;
#define MAXN 2005
#define MAXK 17
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
struct muchie {
	int urm,cost;
};
struct muchie2 {
	int urm, cost, stare;
};
inline bool comp(muchie a, muchie b) {
	return (a.cost>=b.cost); //MIN-HEAP
}
inline bool comp2(muchie2 a, muchie2 b) {
	return (a.cost>=b.cost);
}

int n,m,k,i,j,c[MAXK],x,y,z,l,trebnr,cost[MAXK][MAXK],ref[MAXN],parti[MAXK],nrparti,partmin,poz,costt;
bitset<MAXN> treb,vizitat;
vector<muchie> graf[MAXN];
vector<muchie> heap;
vector<muchie2> heap2;
bitset<10000000> vizitate2;
int min2[10000000];
muchie2 m2,m22;
muchie maux,maux2;

void citire() {
	fin>>n>>m>>k;
	for(i=1;i<=k;i++){		
		fin>>c[i];
		ref[c[i]]=i;
	}
	for(i=1;i<=m;i++) {
		fin>>x>>y>>z;
		maux.cost=z;
		maux.urm=x;
		graf[y].push_back(maux);
		maux.urm=y;
		graf[x].push_back(maux);		
	}
	ref[1]=0;
	ref[n]=k+1;
}

void dijkstra(int nod) {
	//cout<<nod<<"\n";
	vizitat.reset();
	heap.clear();
	maux.urm=nod;
	maux.cost=0;
	heap.push_back(maux);	
	while (trebnr>0) {
		maux=heap[0];
		//cout<<"  "<<maux.urm<<"\n";
		pop_heap(heap.begin(),heap.end(),comp);
		heap.pop_back();
		if (!vizitat[maux.urm]) {
			vizitat[maux.urm]=1;
			if (treb[maux.urm]) {
				trebnr--;
				treb[maux.urm]=0;
				cost[ref[nod]][ref[maux.urm]]=maux.cost;
				cost[ref[maux.urm]][ref[nod]]=maux.cost;
			}
			for(x=0;x<graf[maux.urm].size();x++) {
				//cout<<"     ->"<<graf[maux.urm][x].urm<<"\n";
				if (!vizitat[graf[maux.urm][x].urm]) {					
					maux2.urm=graf[maux.urm][x].urm;
					maux2.cost=maux.cost+graf[maux.urm][x].cost;
					heap.push_back(maux2);
					push_heap(heap.begin(), heap.end(), comp);
				}
			}
		}
	}	
}

void dijkstra2() {
		m2.urm=0;
		m2.cost=0;
		m2.stare=0;
		heap2.push_back(m2);		
		while (!heap2.empty()) {			
			m2=heap2[0];
			pop_heap(heap2.begin(),heap2.end(),comp2);
			heap2.pop_back();
			if (!vizitate2[m2.stare*100+m2.urm]) {				
				vizitate2[m2.stare*100+m2.urm]=1;
				if ( (m2.stare==(1<<(k+1))-1)&&(m2.urm==k+1) ) {
					l=m2.cost;
					return;
				} else
				for(int ii=0;ii<k;ii++) {
					if ( (((m2.stare>>ii)%2)==0) && (m2.urm!=ii+1)) {						
						m22.cost=m2.cost+cost[m2.urm][ii+1];
						m22.urm=ii+1;
						m22.stare=m2.stare+(1<<ii);
						if (!vizitate2[m22.stare*100+m22.urm]) {
							if ( (min2[m22.stare*100+m22.urm]==0)||(min2[m22.stare*100+m22.urm]>m22.cost)) {
								heap2.push_back(m22);
								push_heap(heap2.begin(),heap2.end(),comp2);
								min2[m22.stare*100+m22.urm]=m22.cost;
							}
						}
					}
				}
				if (m2.stare==(1<<k)-1) {
						m22.cost=m2.cost+cost[m2.urm][k+1];
						m22.urm=k+1;
						m22.stare=m2.stare+(1<<k);
						if (!vizitate2[m22.stare*100+m22.urm]) {
							heap2.push_back(m22);
							push_heap(heap2.begin(),heap2.end(),comp2);
						}
				}
			}
		}
}

int main() {
	citire();
	treb[n]=1;
	trebnr=1;
	for(i=1;i<=k;i++) {
		treb[c[i]]=1;
		trebnr++;
	}
	dijkstra(1);
	for(i=1;i<=k;i++) {
		trebnr=1;
		for(j=i+1;j<=k;j++) {
			treb[c[j]]=1;
			trebnr++;
		}
		treb[n]=1;
		
		dijkstra(c[i]);
	}
/*	for(i=0;i<=k+1;i++) {		
		for(j=0;j<=k+1;j++) {
			cout<<cost[i][j]<<" ";
		}
		cout<<"\n";
	}
*/	
	if (k==0) l=cost[0][k+1];
	else {
		
		dijkstra2();
		
	}
	fout<<l<<"\n";
	fout.close();
	return 0;
}