Cod sursa(job #430509)

Utilizator Mishu91Andrei Misarca Mishu91 Data 31 martie 2010 09:23:22
Problema Gather Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)

const int MAX_N = 755;
const int MAX_K = 20;
const int MAX_C = (1 << 15);
const int INF = 0x3f3f3f3f;

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

struct nod
{
	int x, d;
	unsigned int c;
	nod(){};
	nod(int _x, unsigned int _c, int _d)
	{
		x = _x;
		c = _c;
		d = _d;
	}
} a;

int K, N, M, V[MAX_K];
unsigned int D[MAX_N], T[MAX_K][MAX_K][MAX_K], R[MAX_K][MAX_C];
vector <nod> G[MAX_N];

void citire()
{
	fin >> K >> N >> M;

	V[0] = 1;
	for(int i = 1; i <= K; ++i)
		fin >> V[i];

	for(int i = 1; i <= M; ++i)
	{
		int x, y, d;
		unsigned int c;
		fin >> x >> y >> c >> d;
		G[x].push_back(nod(y, c, d));
		G[y].push_back(nod(x, c, d));
	}
}

struct cmp
{
	bool operator() (const int &a, const int &b) const
	{
		return D[a] > D[b];
	}
};

void calc(int nod, int k)
{
	priority_queue <int, vector <int>, cmp> Q;
	char viz[MAX_N];
	memset(D, INF, sizeof D);
	memset(viz, 0, sizeof viz);

	D[V[nod]] = 0;
	viz[V[nod]] = 1;
	for(Q.push(V[nod]); !Q.empty();)
	{
		int act = Q.top();
		Q.pop();
		viz[act] = 0;

		foreach(G[act])
			if(it -> d >= k && D[it -> x] > D[act] + it -> c)
			{
				D[it -> x] = D[act] + it -> c;

				if(viz[it -> x]) continue;
				Q.push(it -> x);
				viz[it -> x] = 1;
			}
	}

	for(int i = 1; i <= K; ++i)
		T[nod][i][k] = D[V[i]];
}

struct cmp2
{
	bool operator()(const nod &a, const nod &b) const
	{
		return a.c > b.c;
	}
};

inline int nrbiti(int x)
{
	int num = 0;
	if(x)
		do ++num; while(x &= (x-1));
	
	return num;	
}

void solve()
{
	priority_queue <nod, vector <nod>, cmp2> Q;
	memset(R, INF, sizeof R);

	R[0][0] = 0;

	for(Q.push(nod(0, 0, 0)); !Q.empty();)
	{
		int nod = Q.top().x;
		unsigned int cost = Q.top().c;
		int conf = Q.top().d;
		Q.pop();

		int nrb = nrbiti(conf);
		//fprintf(stderr, "%d %d %d\n", nod, conf, nrb);
		for(int i = 1; i <= K; ++i)
		{
			if(conf & (1 << (i-1))) continue;
			int newconf = conf + (1 << (i-1));

			if(R[i][newconf] > cost + (nrb+1)*T[nod][i][nrb])
			{
				R[i][newconf] = cost + (nrb+1)*T[nod][i][nrb];
				//fprintf(stderr, "%d %d %d %d %d\n", nod, conf, i, newconf, R[i][newconf]);
				
				a.x = i;
				a.d = newconf;
				a.c = R[i][newconf];
				Q.push(a);
			}
		}
	}

	unsigned int Sol = R[1][(1 << K)-1];
	for(int i = 1; i <= K; ++i)
			Sol = min(Sol, R[i][(1 << K) - 1]);

	fout << Sol;
}

int main()
{
	citire();

	calc(0, 0);
	for(int i = 1; i <= K; ++i)
		for(int j = 1; j <= K; ++j)
			calc(i, j);

//	fprintf(stderr, "%d\n", T[1][2][1]);
	solve();
}