Cod sursa(job #2223143)

Utilizator Juve45UAIC Alexandru Ionita Juve45 Data 19 iulie 2018 09:38:39
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <bits/stdc++.h>

#define dbg(x) cerr<<#x": "<<x<<"\n"
#define dbg_p(x) cerr<<#x": "<<x.first<<","<<x.second<<"\n"
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok cerr<<"OK!\n"

#define st first
#define nd second

using namespace std;

const int N = 2010;
const int inf = 0x3f3f3f3f;
int n, k, m, c[22], d[N], dmin[22][22], a, b, cst, dp[55000][22];
vector <pair<int, int> > v[N];

template<class T>
ostream& operator<<(ostream& out, vector<T> v) {
	out << v.size() << '\n';
	for(auto e : v) out << e << ' ';
	return out;
}


void dijkstra(int ind) {
	int start = c[ind];
	for(int i = 0; i <= n; i++)
		d[i] = inf;
	
	d[start] = 0;

	priority_queue <pair<int, int> > pq;
	pq.push({-d[start], start});

	while(!pq.empty()) {
		auto p = pq.top();
		pq.pop();
		for(auto i : v[p.nd])
			if(d[i.st] > d[p.nd] + i.nd) {
				d[i.st] = d[p.nd] + i.nd;
				pq.push({-d[i.st], i.st});
			}
	}

	for(int i = 0; i <= k + 1; i++)
		dmin[ind][i] = d[c[i]];
}

int main() {
	ios_base::sync_with_stdio(false);
	freopen("ubuntzei.in", "r", stdin);
	freopen("ubuntzei.out", "w", stdout);
	cin >> n >> m >> k;
	for(int i = 1; i <= k; i++)
		cin >> c[i];

	c[0] = 1;
	c[k + 1] = n;

	for(int i = 1; i <= m; i++) {
		cin >> a >> b >> cst;
		v[a].push_back({b, cst});
		v[b].push_back({a, cst});
	}


	for(int i = 0; i <= k + 1; i++)
		dijkstra(i);

	memset(dp, inf, sizeof dp);
	for(int i = 1; i < (1 << k); i++) {

		for(int j = 0; j < k; j++) 
			if(i & (1 << j)) {
				int ant = i - (1 << j);

				if(ant == 0)
					dp[i][j] = dmin[0][j + 1];
				else
					for(int l = 0; l < k; l++) 
						if(ant & (1 << l))
							dp[i][j] = min(dp[i][j], dp[ant][l] + dmin[j + 1][l + 1]);
			}
	}
	int ans = inf, mask = (1 << k) - 1;

	if(k == 0) 
		return cout << dmin[0][k + 1] << '\n', 0;

	for(int i = 0; i < k; i++) 
		ans = min(ans, dp[mask][i] + dmin[i + 1][k + 1]);

	cout << ans << '\n';
}