Cod sursa(job #1162942)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 1 aprilie 2014 06:33:26
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <cstdio>
#include <utility>
#include <vector>
#include <queue>
#include <algorithm>
#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<unsigned> > distg;


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, nod=q.top().second; q.pop();

		if(dist[nod]==c&&(subsetid[nod]==0||nod==1||nod==n))
			for(unsigned i=0;i<Pre[nod].size();++i)
				if(dist[Pre[nod][i].first]>c+Pre[nod][i].second){
					dist[Pre[nod][i].first]=c+Pre[nod][i].second;
					q.push(PUU(dist[Pre[nod][i].first],Pre[nod][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));
	}

	distg.resize(k+3,std::vector<unsigned>(k+3,INF));

	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){
				distg[i][j]=dist[subset[j]];
				distg[j][i]=dist[subset[j]];
			}
	}
}

unsigned getdist(){
	std::vector<std::vector<unsigned> > dp(k+3 ,std::vector<unsigned>(1<<k,INF));

    for(unsigned i=2;i<k+2;++i) dp[i][1<<(i-2)]=distg[1][i];

    for(unsigned s=0;s<(1u<<k);++s){
        for(unsigned i=2;i<k+2;++i){
            unsigned newset= s | (1<<(i-2));

            for(unsigned j=2;j<k+2;++j) if( 1&(s>>(j-2)) )
                if(distg[j][i]!=INF)
                    dp[i][newset]=std::min(dp[i][newset], dp[j][s]+distg[j][i]);
        }

    }

    unsigned m=INF;
    for(unsigned i=1;i<k+2;++i) m=std::min(m,dp[i][(1<<k)-1]+distg[i][k+2]);
    return m;
}


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;
	}

	dijkstra_init();

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

}