Cod sursa(job #553458)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 14 martie 2011 08:24:12
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.65 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

#define maxN 	510
#define maxP 	51
#define oo 		1000000000

int D[maxN][maxP][maxN], dest[maxP], M, P, N, dist[maxN][maxN], dist2[maxN], st[maxN * 6], V[maxN];

int memoizare (int left, int right, int node) {
	if (left > right)
		return 0;
	if (D[left][right][node] != -1)
		return D[left][right][node];

	int ret = oo, i, now;

	for (i = left; i <= right; ++ i) {
		now = memoizare(left, i - 1, dest[i]) + memoizare(i + 1, right, dest[i]) + dist[node][dest[i]];
		if (now < ret)
			ret = now;
	}

	D[left][right][node] = ret;
	return ret;
}

int main () {
	int i, j, k, x, y, c;

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

	scanf("%d%d%d", &P, &N, &M);

	for (i = 1; i <= N; ++ i)
		for (j = 1; j <= N; ++ j)
			if (i != j)
				dist[i][j] = oo;

	for (i = 1; i <= P; ++ i)
		for (j = 1; j <= P; ++ j)
			for (k = 1; k <= N; ++ k)
				D[i][j][k] = -1;


	for (i = 1; i <= M; ++ i) {
		scanf("%d%d%d", &x, &y, &c);
		dist[x][y] = min(dist[x][y], c);
		dist[y][x] = min(dist[y][x], c);
	}


	for (dest[0] = 1, j = 1; j <= P; ++ j)
		scanf("%d", &dest[j]);

	for (k = 0; k <= P; ++ k) {
		for (j = 1; j <= N; ++ j)
			dist2[j] = oo;
		dist2[dest[k]] = 0;
		st[st[0] = 1] = dest[k];
		V[dest[k]] = 1;

		for (i = 1; i <= st[0]; ++ i) {
			int nodcur = st[i];
			for (j = 1; j <= N; ++ j) {
				if (dist2[j] > dist2[nodcur] + dist[nodcur][j]) {
					dist2[j] = dist2[nodcur] + dist[nodcur][j];
					if ( ! V[j]) {
						st[ ++ st[0]] = j;
						V[j] = 1;	
					}
				}
			}
			V[nodcur] = 0;
		}
		for (i = 1; i <= N; ++ i)
			dist[dest[k]][i] = dist2[i];
	}
	printf("%d\n", memoizare(1, P, 1));
	return 0;
}