Cod sursa(job #1077775)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 11 ianuarie 2014 17:28:22
Problema Ubuntzei Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 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 204
#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 min_lg = inf;
int ans = inf;
int cnt;

void back(int k) {
	if (cnt + (K - k + 1) * min_lg > ans) return;
	if (k == K + 1) {
		cnt += d[n][ c[st[k - 1]] ];
		if (cnt < ans) 
			ans = cnt;
		cnt -= d[n][ c[st[k - 1]] ];
	}
	else {
		for (int i = 1; i <= K; ++i) {
			if (!Used[i]) {
				Used[i] = 1;
				st[k] = i;
				cnt += d[ c[st[k - 1]] ][ c[i] ];
				back(k + 1);
				Used[i] = 0;
				cnt -= d[ c[st[k - 1]] ][ c[i] ];
			}
		}
	}
}

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;
		min_lg = min(min_lg, 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);
		}
		if (!K) {
			ans = d[1][n];
			break;
		}
	}
	c[0] = 1;
	if (K) back(1);
	fout << ans << '\n';
	return 0;
}