Cod sursa(job #831354)

Utilizator deneoAdrian Craciun deneo Data 8 decembrie 2012 15:20:35
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.62 kb
#include <fstream>
#include <vector>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

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

#define MAXN 2001

int N, M, K, pd[1 << 15][16], cost[MAXN][MAXN];
int dist[MAXN][MAXN], C[16];

vector <int> g[MAXN];

void doDijkstra(int nod) {
	priority_queue< pair <int, int> > queue;
	
	queue.push(make_pair(0, nod));
	
	while (!queue.empty()) {
		pair<int, int> a;
		a = queue.top();
		queue.pop();
		for (int i = 0; i < g[a.second].size(); ++i)
			if (dist[nod][g[a.second][i]] > a.first + cost[a.second][g[a.second][i]] || dist[nod][g[a.second][i]] == 0) {
				dist[nod][g[a.second][i]] = a.first + cost[a.second][g[a.second][i]];
				queue.push(make_pair(dist[nod][g[a.second][i]], g[a.second][i]));
			}
	}
}

void doPD() {
	pd[0][0] = 1;
	for (int i = 0; i < (1 << K); ++i) 
		for (int j = 0; j <= K; ++j) 
			for (int t = 0; t < K; ++t) {
				if ((i & (1 << t)) == 0 && pd[i][j] != 0) {
					if (pd[i | (1 << t)][t + 1] == 0 && t + 1 != j) 
						pd[i | (1 << t)][t + 1] = pd[i][j] + dist[C[j]][C[t + 1]];
					else
						pd[i | (1 << t)][t + 1] = min (pd[i | (1 << t)][t + 1], pd[i][j] + dist[C[j]][C[t + 1]]);
				}
	}
}
int main () {
	fin >> N >> M;
	
	fin >> K; C[1] = 1; ++K;
	for (int i = 2; i <= K; ++i)
		fin >> C[i];
	
	for (int i = 1; i <= M; ++i) {
		int x, y, z;
		fin >> x >> y >> z;
		cost[y][x] = cost[x][y] = z;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	
	for (int i = 1; i <= K; ++i) 
		doDijkstra(i);
		
	doPD();
	int rez = 1 << 30;
	for (int i = 1; i <= K; ++i)
		rez = min (rez, pd[(1 << K) - 1][i] + dist[i][N]);
	
	fout << rez - 1;
	return 0;
}