Cod sursa(job #1236477)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 1 octombrie 2014 23:28:23
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <fstream>
#include <queue>
#include <vector>
#include <bitset>
#include <algorithm>
#define DIMN 755
#define DIMK 16
#define INF 1000000000
#define vint vector<int>::iterator
#define infile "gather.in"
#define outfile "gather.out"

using namespace std;

ifstream f(infile);
ofstream g(outfile);

bitset<DIMN> ok;

vector<int> L[DIMN];

queue<int> Q;

int D[DIMK][DIMN][DIMK], DD[DIMN][1 << DIMK], C[DIMN][DIMN], cost[DIMN][DIMN], Cells[DIMN];

int n, k, m, a, b, c, d;

int B[1 << DIMK];

void dist(int p, int cmin) {
	for (int i = 1; i <= n; ++i)
		D[p][i][cmin] = INF, ok[i] = 0;
	D[p][Cells[p]][cmin] = 0;
	Q.push(Cells[p]);
	while (!Q.empty()) {
		int nod = Q.front();
		Q.pop();
		ok[nod] = 0;
		for (vint it = L[nod].begin(); it != L[nod].end(); ++it)
		if (C[nod][*it] >= cmin && D[p][*it][cmin] > D[p][nod][cmin] + cost[nod][*it]) {
			D[p][*it][cmin] = D[p][nod][cmin] + cost[nod][*it];
			if (!ok[*it]) {
				ok[*it] = 1;
				Q.push(*it);
			}
		}
	}
}

int main() {
	f >> k >> n >> m;
	for (int i = 1; i <= k; ++i)
		f >> Cells[i];
	Cells[0] = 1;
	for (int i = 1; i <= m; ++i) {
		f >> a >> b >> c >> d;
		cost[a][b] = cost[b][a] = c;
		C[a][b] = C[b][a] = d;
		L[a].push_back(b);
		L[b].push_back(a);
	}
	for (int i = 1; i < (1 << DIMK); ++i)
		B[i] = B[i / 2] + i % 2;
	for (int i = 0; i <= k; ++i)
	for (int j = 0; j <= k; ++j)
		dist(i, j);
	for (int i = 0; i <= k; ++i)
	for (int j = 0; j < (1 << DIMK); ++j)
		DD[i][j] = INF;
	DD[0][1] = 0;
	for (int t = 1; t < (1 << (k+1)); ++t)
	for (int i = 0; i <= k; ++i)
	if (t & (1 << i)) {
		for (int j = 0; j <= k; ++j)
		if (!(t & (1 << j)) && D[i][Cells[j]][B[t] - 1] != INF)
		if (DD[j][t | (1 << j)] > DD[i][t] + B[t] * D[i][Cells[j]][B[t] - 1])
			DD[j][t | (1 << j)] = DD[i][t] + B[t] * D[i][Cells[j]][B[t] - 1];
	}
	int ans = INF;
	for (int i = 1; i <= k; ++i)
		ans = std::min(ans, DD[i][(1 << (k + 1)) - 1]);
	g << ans;
	return 0;
}

//This room. This bullet. There's a bullet for everyone. And a time. And a place. Yes... maybe this is how it has to be. - 47