Cod sursa(job #1125163)

Utilizator antonioteoZait Teodor Antonio antonioteo Data 26 februarie 2014 16:06:43
Problema Ubuntzei Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <queue>
#include <fstream>
#include <cstring>
#include <algorithm>
using namespace std;

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

#define INF 0x3f3f3f3f
#define NMAX 2001
#define KMAX 17

struct Nod {
	int u;
	int l;
	Nod *next;
};
Nod *v[NMAX];
Nod *G[KMAX];

int i, j, N, M, K;
int x, y, z;

bool isK[NMAX];

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

int pos[NMAX];
int nod[KMAX];
int d[NMAX][NMAX];
int cost[KMAX][KMAX];
int dp[(1 << KMAX)][KMAX];

struct cmp {
	bool operator()(const int &a, const int &b) {
		if (d[i][a] > d[i][b]) return 1;
		return 0;
	}
};

priority_queue <int, vector <int>, cmp> Q;

int main() {
	fin >> N >> M >> K;
	nod[0] = 1;  nod[K + 1] = N;
	isK[1] = isK[N] = true;
	pos[1] = 0; pos[N] = K + 1;
	for (i = 1; i <= K; ++i) {
		fin >> nod[i];
		isK[nod[i]] = true;
		pos[nod[i]] = i;
	}
	K += 2;
	for (i = 1; i <= M; ++i) {
		fin >> x >> y >> z;
		add(x, y, z, v);
		add(y, x, z, v);
	}
	for (i = 1; i <= N; ++i) {
		memset(d[i], INF, sizeof(d[i]));
		d[i][i] = 0;
		Q.push(i);
		while (!Q.empty()) {
			x = Q.top();
			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;
					if (isK[i] && isK[it->u])
						cost[i][it->u] = d[i][it->u];
					Q.push(it->u);
				}
			}
			Q.pop();
		}
	}
	for (i = 0; i < K - 1; ++i) {
		for (j = i + 1; j < K; ++j) {
			add(nod[j], nod[i], cost[ nod[i] ][ nod[j] ], G);
			add(nod[i], nod[j], cost[ nod[i] ][ nod[j] ], G);
		}
	}
	int lim = (1 << K);
	memset(dp, INF, sizeof(dp));
	dp[1][0] = 0;
	for (i = 1; i < lim; ++i) {
		for (j = 0; j < K; ++j) {
			if (i & (1 << j)) {
				for (Nod *it = G[nod[j]]; it; it = it->next)
					if (i & (1 << pos[it->u]))
						dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][pos[it->u]] + cost[it->u][nod[j]]);
			}
		}
	}
	fout << dp[lim - 1][K - 1] << '\n';
	return 0;
}