Cod sursa(job #1607658)

Utilizator pas.andreiPopovici Andrei-Sorin pas.andrei Data 21 februarie 2016 14:56:08
Problema Ubuntzei Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
#include <functional>
#include <string>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <bitset>
#include <stack>
#include <iomanip>
#define MOD 1000000007
#define NMAX 2005
#define INF 0x3f3f3f3f

using namespace std;

FILE *fin = freopen("ubuntzei.in", "r", stdin);
FILE *fout = freopen("ubuntzei.out", "w", stdout);

typedef pair<int, int> pii;

int pos[18], dist[18][NMAX], dp[18][1<<18], k;
bool viz[NMAX];
vector<pii> v[NMAX];

void dijkstra(int start, int n);
int cmin(int x, int mask);

int main() {
	int n, m, i, x, y, c;

	cin >> n >> m >> k;
	for (i = 1; i <= k; ++i)
		cin >> pos[i];

	for (i = 0; i < m; ++i) {
		cin >> x >> y >> c;

		v[x].push_back({ c, y });
		v[y].push_back({ c, x });
	}

	pos[0] = 1;
	pos[k + 1] = n;
	k += 2;
	
	for (i = 0; i < k; ++i)
		for (int j = 0; j < (1 << k); ++j)
			dp[i][j] = -1;

	dijkstra(1, n);
	for (i = 1; i < k; ++i) {
		dijkstra(pos[i], n);
		dp[i][(1 << k) - 1] = 0;
	}

	cout << cmin(0, 1);

	return 0;
}

int cmin(int x, int mask) {
	int &ret = dp[x][mask];

	if (ret != -1)
		return ret;

	int i, res = INF;
	for (i = 0; i < k; ++i)
		if (!(mask&(1 << i)))
			res = min(res, dist[pos[x]][pos[i]] + cmin(i, mask | (1 << i)));

	return ret = res;
}

void dijkstra(int start, int n) {
	int x,i,y,c;

	for (i = 1; i <= n; ++i) {
		dist[start][i] = INF;
		viz[i] = 0;
	}

	dist[start][start] = 0;
	priority_queue<pii, vector<pii>, greater<pii> > pq;
	pq.push({ 0, start });

	while (!pq.empty()) {
		int x = pq.top().second;
		pq.pop();

		if (!viz[x]) {
			viz[x] = 1;

			for (i = 0; i < v[x].size(); ++i) {
				c = v[x][i].first;
				y = v[x][i].second;

				if (dist[start][y] > dist[start][x] + c) {
					dist[start][y] = dist[start][x] + c;
					pq.push({ dist[start][y], y });
				}
			}
		}
	}
}