Cod sursa(job #176875)

Utilizator plastikDan George Filimon plastik Data 11 aprilie 2008 20:49:34
Problema Team Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
// Team, Infoarena/Lot 2006
// http://infoarena.ro/problema/team

#define _CRT_SECURE_NO_DEPRECATE
#include <cstdio>
#include <climits>
#include <list>
#include <set>
using namespace std;

const int NMAX = 512;
const int PMAX = 64;

int p, n, m;
list<pair<int, int> > Neighb[NMAX];

int Dist[NMAX][NMAX], Ans[PMAX][PMAX][NMAX];
int End[PMAX];
set<int> Cities;

void roy_floyd() {
	int k, i, j;

	for (k = 1; k <= n; ++ k)
		for (i = 1; i <= n; ++ i) {
			if (k == i)
				continue;
			for (j = 1; j <= n; ++ j) {
				if (Dist[i][k] == INT_MAX || Dist[k][j] == INT_MAX)
					continue;
				if (Dist[i][j] > Dist[i][k] + Dist[k][j])
					Dist[i][j] = Dist[i][k] + Dist[k][j];
			}
		}
}

int main() {

	freopen("team.in", "r", stdin);
	freopen("team.out", "w", stdout);

	scanf("%d %d %d", &p, &n, &m);
	int i, j, v1, v2, c;

	for (i = 1; i <= n; ++ i)
		for (j = 1; j <= n; ++ j)
			Dist[i][j] = INT_MAX;
	for (i = 1; i <= n; ++ i)
		Dist[i][i] = 0;

	for (i = 0; i < m; ++ i) {
		scanf("%d %d %d", &v1, &v2, &c);
		Neighb[v1].push_back(make_pair(v2, c));
		Neighb[v2].push_back(make_pair(v1, c));
		Dist[v1][v2] = Dist[v2][v1] = c;
	}
	for (i = 1; i <= p; ++ i) {
		scanf("%d", &End[i]);
		Cities.insert(End[i]);
	}
	Cities.insert(1);

	roy_floyd();

	set<int>::iterator si;
	int k, l, ans;

	for (l = 1; l <= p; ++ l)
		for (i = 1; i <= p - l + 1; ++ i)
			for (si = Cities.begin(); si != Cities.end(); ++ si)
				Ans[i][i + l - 1][*si] = INT_MAX;

	for (i = 1; i <= p; ++ i)
		for (j = 1; j <= n; ++ j)
			Ans[i][i][j] = Dist[j][End[i]];

	for (l = 2; l <= p; ++ l)
		for (i = 1; i <= p - l + 1; ++ i) {
			j = i + l - 1;
			for (si = Cities.begin(); si != Cities.end(); ++ si) {
				ans = INT_MAX;
				for (k = i; k <= j; ++ k) {
					if (Ans[i][k - 1][End[k]] == INT_MAX ||  Ans[k + 1][j][End[k]] == INT_MAX || Dist[*si][End[k]] == INT_MAX)
						continue;
					ans = min(ans, Ans[i][k - 1][End[k]] + Ans[k + 1][j][End[k]] + Dist[*si][End[k]]);
				}
				Ans[i][j][*si] = ans;
			}
		}

	printf("%d\n", Ans[1][p][1]);

	return 0;
}