Cod sursa(job #357113)

Utilizator Mishu91Andrei Misarca Mishu91 Data 17 octombrie 2009 22:53:57
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <fstream>
#include <bitset>
#include <vector>
#include <queue>

using namespace std;

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

#define MAX_N 505
#define MAX_P 55
#define INF 0x3f3f3f3f

#define nd first
#define cst second

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

int P, N, M;
vector <pair <int, int> > G[MAX_N];
int D[MAX_P], Dst[MAX_P][MAX_P], Bst[MAX_N];
int Sol[MAX_P][MAX_P][MAX_P];

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

	for(int i = 1; i <= M; ++i)
	{
		int x, y, c;
		fin >> x >> y >> c;

		G[x].push_back( make_pair(y,c) );
		G[y].push_back( make_pair(x,c) );
	}

	for(int i = 1; i <= P; ++i)
		fin >> D[i];
	D[0] = 1;
}

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

void Dijkstra(int k)
{
	memset(Bst, INF, sizeof Bst);
	Bst[k] = 0;
	priority_queue<int, vector <int>, cmp> Q;
	bitset <MAX_N> inq;
	inq[k] = 1;

	for(Q.push(k); !Q.empty(); Q.pop())
	{
		int nod = Q.top();
		inq[nod] = 0;

		foreach(G[nod])
		{
			int act = it -> nd;
			int cst = it -> cst;

			if(Bst[act] > Bst[nod] + cst)
			{
				Bst[act] = Bst[nod] + cst;
				if(!inq[act])
				{
					Q.push(act);
					inq[act] = 1;
				}
			}
		}
	}
}

int solve(int i, int j, int nod)
{
	if(Sol[i][j][nod] < INF) return Sol[i][j][nod];
	if(i > j) return 0;

	for(int k = i; k <= j; ++k)
		Sol[i][j][nod] = min(Sol[i][j][nod], solve(i, k-1, k) + solve(k+1, j, k) + Dst[nod][k]);

	return Sol[i][j][nod];
}

int main()
{
	citire();

	for(int i = 0; i <= P; ++i)
	{
		Dijkstra(D[i]);

		for(int j = 0; j <= P; ++j)
			Dst[i][j] = Bst[D[j]];
	}

	memset(Sol, INF, sizeof Sol);
	fout << solve(1, P, 0) << "\n";
}