Cod sursa(job #1126069)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 26 februarie 2014 21:07:35
Problema Ubuntzei Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
#include <fstream>
#include <utility>
#include <vector>
#include <list>
#include <queue>
#include <limits>

const unsigned INF = std::numeric_limits<unsigned>::max()/2-5;

typedef std::pair<unsigned, unsigned> PUU;
typedef std::pair<unsigned, PUU> PUP;


inline unsigned Dijkstra_modif(const unsigned &N, const unsigned &K,
							   const std::vector< std::list<PUU> > &Adj,
							   const std::vector< unsigned > &subsetmask);


int main(){
	std::ifstream fin("ubuntzei.in");
	std::ofstream fout("ubuntzei.out");

	unsigned N,M; unsigned short K; //K<=15 => operatii pe biti
	fin>>N>>M>>K;

	std::vector< unsigned > subsetmask(N+1,0);
	for(unsigned i=0;i<K;++i){
		unsigned x; fin>>x;
		subsetmask[x]=1<<i;
	}

	std::vector< std::list<PUU> > Adj(N+1);

	for(unsigned i=0;i<M;++i){
		unsigned x,y,c; fin>>x>>y>>c;
		Adj[x].push_back(PUU(y,c));
		Adj[y].push_back(PUU(x,c));
	}

	fout<<Dijkstra_modif(N,K,Adj,subsetmask)<<'\n';
}


inline unsigned Dijkstra_modif(const unsigned &N, const unsigned &K,
							   const std::vector< std::list<PUU> > &Adj,
							   const std::vector< unsigned > &subsetmask){
	std::vector< std::vector<unsigned> > dist(N+1,std::vector<unsigned>(1<<K,INF));
	std::vector< std::vector<bool> > visited(N+1,std::vector<bool>(1<<K,false));

	std::priority_queue<PUP> pq;
	pq.push(PUP(0,PUU(1,0))); dist[1][0]=0;

	while(!pq.empty()){
		unsigned cdist=pq.top().first, cnod=pq.top().second.first, cset=pq.top().second.second;
		pq.pop(); visited[cnod][cset]==true;

		if(cdist==dist[cnod][cset]){
			if(subsetmask[cnod]&&((cset&subsetmask[cnod])==0)){
				unsigned newset=cset|subsetmask[cnod];
				if((!visited[cnod][newset])&&dist[cnod][newset]>dist[cnod][cset]){
					dist[cnod][newset]=dist[cnod][cset];
					pq.push(PUP(dist[cnod][newset],PUU(cnod,newset)));
				}
			}
			for(auto it=Adj[cnod].begin();it!=Adj[cnod].end();++it){
				unsigned ngb=it->first;
				if(!visited[ngb][cset]&&dist[ngb][cset]>dist[cnod][cset]+it->second){
					dist[ngb][cset]=dist[cnod][cset]+it->second;
					pq.push(PUP(dist[ngb][cset],PUU(ngb,cset)));
				}
			}

		}
	}

	return dist[N][(1<<K)-1];
}