Cod sursa(job #2138269)

Utilizator brczBereczki Norbert Cristian brcz Data 21 februarie 2018 15:12:57
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.56 kb
#include<bits/stdc++.h>

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

#define cin fin
#define cout fout
#define int long long

const int maxn = 2002;

int n,m,k;
vector<int> ks;
vector<pair<int,int> > g[maxn];
int dist[maxn][maxn];
int dp[1<<16][20];

void reload(int vx) {
	for(int i=1;i<=n;++i) {
		dist[vx][i] = (1e12);
	}
}

void solve(int vx) {

	reload(vx);
	priority_queue<pair<int,int>, vector<pair<int,int> >, greater<pair<int,int> > > H;
	H.push({0,vx});
	dist[vx][vx] = 0;
	while(!H.empty()) {
		pair<int,int> t = H.top();
		H.pop();
		if(dist[vx][t.second]!=t.first) continue;
		for(pair<int,int> nei : g[t.second]) {
			if(dist[vx][nei.second] <= nei.first + t.first) continue;
			dist[vx][nei.second] = nei.first + t.first;
			H.push({nei.first + t.first,nei.second});
		}
	}
}

signed main() {

	cin >> n >> m;
	cin >> k;
	ks.resize(k);
	for(int i=0;i<k;++i) cin >> ks[i];

	int x,y,c;
	for(int i=0;i<m;++i) {
		cin >> x >> y >> c;
		g[x].push_back({c,y});
		g[y].push_back({c,x});
	}
	
	solve(1);
	for(int vx : ks) solve(vx);

	if(!k) {
		cout << dist[1][n] << '\n';
		return 0;
	}

	for(int i=0;i<(1<<16);++i) for(int j=0;j<20;++j) dp[i][j] = (1e12);

	for(int i=0;i<k;++i) dp[1<<i][i] = dist[1][ks[i]];

	for(int i=2;i<=(1<<k)-1;++i) {
		for(int j=0;j<k;++j) {
			if((i>>j)&1) {
				for(int ki = 0;ki < k; ++ki) {
					dp[i][j] = min(dp[i][ki],dp[i ^ (1<<j)][ki] + dist[ks[ki]][ks[j]]); 		
				}				
			}
		}
	}

	int ans = (1e12);
	for(int i=0;i<k;++i) {
		ans = min(ans,dp[(1<<k)-1][i] + dist[ks[i]][n]);
	}

	cout << ans << '\n';

	return 0;
}