Cod sursa(job #1162327)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 31 martie 2014 19:22:48
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <cstdio>
#include <utility>
#include <vector>
#include <queue>
#include <limits>

typedef std::pair<unsigned, unsigned> PUU;
const unsigned INF=std::numeric_limits<unsigned>::max()/2;

unsigned n,m,k;
std::vector<short> subset;
std::vector<unsigned short> subsetid;
std::vector<std::vector<PUU> > Adj;


void dijkstra_modified(unsigned source, std::vector<unsigned> &dest, const std::vector<std::vector<PUU> > &Pre){
	std::vector<unsigned> dist(n+1,INF);
	dist[source]=0;
	std::priority_queue<PUU,std::vector<PUU>,std::greater<PUU> > q;

	for(unsigned i=0;i<Pre[source].size();++i){
		q.push(PUU(Pre[source][i].second,Pre[source][i].first));
		dist[Pre[source][i].first]=Pre[source][i].second;
	}

	while(!q.empty()){
		unsigned c=q.top().first, n=q.top().second; q.pop();

		if(dist[n]==c&&subsetid[n]==0)
			for(unsigned i=0;i<Pre[n].size();++i)
				if(dist[Pre[n][i].first]>c+Pre[n][i].second){
					dist[Pre[n][i].first]=c+Pre[n][i].second;
					q.push(PUU(dist[Pre[n][i].first],Pre[n][i].first));
				}
	}
	dest.swap(dist);
}

void dijkstra_init(){
	std::vector<std::vector<PUU> > Pre(n+1);
	for(unsigned i=0;i<m;++i){
		unsigned a,b,c; scanf("%u %u %u",&a,&b,&c);
		Pre[a].push_back(PUU(b,c)); Pre[b].push_back(PUU(a,c));
	}

	std::vector<unsigned> dist;
	for(unsigned i=1;i<=k+2;++i){
		dijkstra_modified(subset[i],dist,Pre);

		for(unsigned j=i+1;j<=k+2;++j)
			if(dist[subset[j]]!=INF){
				Adj[i].push_back(PUU(j,dist[subset[j]]));
				Adj[j].push_back(PUU(i,dist[subset[j]]));
			}
	}
}

struct Tripl{
	unsigned c,nod,ss;
	Tripl(unsigned x,unsigned y,unsigned z){ c=x; nod=y; ss=z; }
};
class TriplComp{
	public: bool operator()(const Tripl &a, const Tripl &b){ return (a.c>b.c); }
};

unsigned dijkstra_exp(){
	/*for(unsigned i=1;i<=k+2;++i){
		printf("%u:\n",i);
		for(unsigned j=0;j<Adj[i].size();++j) printf("  %d %d\n",Adj[i][j].first,Adj[i][j].second);
	}*/

	std::vector<std::vector<unsigned> > dist(k+3,std::vector<unsigned>(1<<k,INF));
	//dist[0].resize(0); //in case of MLE
	std::priority_queue<Tripl,std::vector<Tripl>,TriplComp> q;
	q.push(Tripl(0,1,0)); dist[1][0]=0;

	while(!q.empty()){
		unsigned c=q.top().c, n=q.top().nod, ss=q.top().ss; q.pop();

		if(c==dist[n][ss])
			for(unsigned i=0;i<Adj[n].size();++i){
				unsigned ns=(Adj[n][i].first==k+2)?ss:(ss|(1<<(Adj[n][i].first-2)));
				if(dist[Adj[n][i].first][ns]>c+Adj[n][i].second){
					dist[Adj[n][i].first][ns]=c+Adj[n][i].second;
					q.push(Tripl(dist[Adj[n][i].first][ns],Adj[n][i].first,ns));
				}
			}
	}


	return dist[k+2][(1<<k)-1];
}


int main(){
	std::freopen("ubuntzei.in","r",stdin);
	std::freopen("ubuntzei.out","w",stdout);

	std::scanf("%u %u %u",&n,&m,&k);

	subset.resize(k+3); subsetid.resize(n+1,0);
	subset[1]=1; subset[k+2]=n;
	subsetid[1]=1; subsetid[n]=k+2;
	for(unsigned i=2;i<k+2;++i){
		std::scanf("%hu",&subset[i]);
		subsetid[subset[i]]=i;
	}

	Adj.resize(k+3);

	dijkstra_init();

	unsigned L=dijkstra_exp();
	printf("%u\n",L);

}