Cod sursa(job #1077724)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 11 ianuarie 2014 16:49:09
Problema Ubuntzei Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
// Dijkstra cu heap ,,de mana", O(K! * N * M * logN)
#include <algorithm>
#include <fstream>
#include <cstring>
#include <queue>
using namespace std;

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

#define nmax 2004
#define inf 0x3f3f3f3f
#define T (u >> 1)
#define L (u << 1) 
#define R (L | 1)

struct nod {
	int u;
	int l;
	nod *next;
};
nod *v[nmax];

inline void add(int i, int j, int leg) {
	nod *p = new nod;
	p->u = j;
	p->l = leg;
	p->next = v[i];
	v[i] = p;
}

int i, n, m, K;
int a, b, lg;
int x, dim;

int c[nmax];
int H[nmax];
int d[nmax][nmax];

inline void upheap(int u) {
	while (u != 1 && d[i][H[u]] < d[i][H[T]]) swap(H[u], H[T]), u = T;
}

inline void downheap(int u) {
	while (1) {
		int m = u;
		if (L <= dim && d[i][H[L]] < d[i][H[u]]) m = L;
		if (R <= dim && d[i][H[R]] < d[i][H[u]]) m = R;
		if (m == u) 
			break;
		swap(H[u], H[m]);
		m = u;
	}
}

int Used[16];
int st[16];

int ans = inf;
int cnt;

inline void solve() {
	cnt = d[1][ c[st[1]] ];
	for (int j = 1; j < K; ++j)
		cnt += d[ c[st[j]] ][ c[st[j + 1]] ];
	cnt += d[n][ c[st[K]] ];
	if (cnt < ans) 
		ans = cnt;
}

void back(int k) {
	if (k == K + 1) solve();
	else {
		for (int i = 1; i <= K; ++i) {
			if (!Used[i]) {
				Used[i] = 1;
				st[k] = i;
				back(k + 1);
				Used[i] = 0;
			}
		}
	}
}

queue <int> Q;

int main() {
	fin >> n >> m;
	fin >> K;
	for (i = 1; i <= K; ++i) fin >> c[i];
	for (i = 1; i <= m; ++i) {
		fin >> a >> b >> lg;
		add(a, b, lg);
		add(b, a, lg);
	}
	memset(d, inf, sizeof(d));
	for (i = 1; i <= n; ++i) {
		d[i][i] = 0;
		dim = 1;
		H[1] = i;
		while (dim) {
			x = H[1];
			for (nod *it = v[x]; it; it = it->next) {
				if (d[i][x] + it->l < d[i][it->u]) {
					d[i][it->u] = d[i][x] + it->l;
					++dim;
					H[dim] = it->u;
					upheap(dim);
				}
			}
			swap(H[1], H[dim]);
			--dim;
			downheap(1);
		}
	}
	back(1);
	if (!K) fout << d[1][n] << '\n';
	else
		fout << ans << '\n';
	return 0;
}