Cod sursa(job #1607757)

Utilizator pas.andreiPopovici Andrei-Sorin pas.andrei Data 21 februarie 2016 16:18:49
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 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[1<<18][18], k;
bool viz[NMAX];
vector<pii> v[NMAX];

void dijkstra(int start, int n);

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

	cin >> n >> m >> k;
	for (i = 0; i < k; ++i) {
		cin >> pos[i];
		--pos[i];
	}

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

		v[x-1].push_back({ c, y-1 });
		v[y-1].push_back({ c, x-1 });
	}
	
	memset(dp, 0x3f3f3f3f, sizeof(dp));
	dp[0][0] = 0;
	dijkstra(0, n);

	if (k == 0) {
		cout << dist[0][n - 1];
		return 0;
	}

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

	for (l = 1; l < (1 << k); ++l)
		for (j = 0; j < k; ++j)
			if ((l & (1 << j)))
				for (i = 0; i < k; ++i)
					if ((l & (1 << i)) == 0)
						dp[l | (1 << i)][i] = min(dp[l | (1 << i)][i], dp[l][j] + dist[pos[j]][pos[i]]);

	int res = INF;
	for (i = 0; i<k; ++i)
		res = min(res, dp[(1 << k) - 1][i] + dist[pos[i]][n - 1]);
	cout << res << '\n';

	return 0;
}

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

	for (i = 0; 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 });
				}
			}
		}
	}
}