Cod sursa(job #41067)

Utilizator MariusMarius Stroe Marius Data 27 martie 2007 22:18:14
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <cstdio>
#include <memory>
using namespace std;

const char iname[] = "team.in";
const char oname[] = "team.out";

#define MAX_P 64
#define MAX_N 512
#define INF   1e9

int P, N, M;

int C[MAX_N][MAX_N];

int D[MAX_P];

int X[MAX_P][MAX_P];

int R[MAX_P][MAX_P][MAX_P];


void read_in(void)
{
	memset(C, 1, sizeof(C));
	scanf("%d", & P);
	scanf("%d", & N);
	for (scanf("%d", & M); M > 0; -- M) {
		int x, y, c;
		scanf("%d %d %d", & x, & y, & c);
		C[x][y] = C[y][x] = c;
	}
	D[0] = 1;
	for (int i = 1; i <= P; ++ i)
		scanf("%d", D + i);
}

void dijkstra(const int s, int D[], int S[])
{
	for (int i = 1; i <= N; ++ i)
		D[i] = INF, S[i] = 0;
	D[s] = 0;
	for (int stp = 1; stp < N; ++ stp) {
		int nod = 0;
		for (int i = 1; i <= N; ++ i)
			if (S[i] == 0 && (nod == 0 || D[nod] > D[i]))	   
				nod = i;
		for (int i = 1; i <= N; ++ i)
			if (D[i] > D[nod] + C[nod][i])
				D[i] = D[nod] + C[nod][i];
		S[nod] = 1;
	}
}

int f(int k, int i, int j)
{
	if (i > j)	return 0;
	if (R[k][i][j] >= 0)  return R[k][i][j];
	if (i == j && k == i) return 0;

	R[k][i][j] = INF;
	for (int u = i; u <= j; ++ u) {
		int temp = X[u][k] + f(u, i, u - 1) + f(u, u + 1, j);
		if (R[k][i][j] > temp)
			R[k][i][j] = temp;
	}
	return R[k][i][j];
}

int main(void)
{
	freopen(iname, "r", stdin);
	read_in();
	int L[MAX_N];
	int S[MAX_N];
	for (int i = 0; i <= P; ++ i) {
		dijkstra(D[i], L, S);
		for (int j = 0; j <= P; ++ j)
			X[i][j] = L[D[j]];
	}
	memset(R, 255, sizeof(R));
	freopen(oname, "w", stdout);
	printf("%d\n", f(0, 1, P));
	return 0;
}