Cod sursa(job #298534)

Utilizator savimSerban Andrei Stan savim Data 6 aprilie 2009 10:49:12
Problema Team Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <stdio.h>
#include <string.h>

#include <algorithm>

#define MAX_N 512
#define MAX_P 64
#define inf 2147000000

int n, m, p, i, j, k, t, x, y, cst, st, dr, val, sol;
int C[MAX_N][MAX_N], D[MAX_N][MAX_N], leg[MAX_N][MAX_N];
int stop[MAX_N], viz[MAX_N];
int coada[MAX_N * MAX_N];

int c[MAX_P][MAX_P][MAX_N];

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

	scanf("%d", &p);
	scanf("%d", &n);
	scanf("%d", &m);
	for (i = 1; i <= m; i++) {
		scanf("%d %d %d", &x, &y, &cst);
		C[x][y] = C[y][x] = cst;
		leg[x][y] = leg[y][x] = 1;
	}
	for (i = 1; i <= p; i++)
		scanf("%d", &stop[i]);
}

void bellman_ford() {
	for (i = 1; i <= p; i++) {
		//pentru fiecare persoana de la 1 la p, aflu folosind algoritmul lui bellman - ford distanta de la oricare nod la el
		st = 0; dr = 1;
		coada[1] = stop[i];
		viz[stop[i]] = i;

		for (j = 1; j <= n; j++) D[stop[i]][j] = inf;
        D[stop[i]][stop[i]] = 0;

        while (st < dr) {
			viz[st] = i - 1;
			st++;
			for (j = 1; j <= n; j++)
		   		if (leg[coada[st]][j] && 
					D[stop[i]][j] > D[stop[i]][coada[st]] + C[j][coada[st]] && 
					viz[j] != i) {
						viz[j] = i;
						coada[++dr] = j;
						D[stop[i]][j] = D[j][stop[i]] = D[stop[i]][coada[st]] + C[j][coada[st]];
					}
		}
	}	
}

void dinamica() {
    memset(c, -1, sizeof(c));

	sol = inf;
	for (j = 0; j < p; j++)
		for (i = 1; i + j <= p; i++)
			for (k = 1; k <= p; k++) {
				//c[i][j][k] = costul minim pentru a rezolva intervalul de la i la i + j, fiind in statia k
				
			 	for (t = 0; t < j; t++) {
					val = c[i][t][stop[i + t + 1]] + D[stop[k]][stop[i + t + 1]];
					if (j >= t + 2) val += c[i + t + 2][j - t - 2][stop[i + t + 1]];
						
					if (c[i][j][stop[k]] > val || c[i][j][stop[k]] < 0) 
						c[i][j][stop[k]] = val;
				}
				if (j == 0) c[i][0][stop[k]] = D[stop[k]][stop[i]];
				
				if (j == p - 1)
					if (c[i][j][stop[k]] + D[1][stop[k]] < sol) 
						sol = c[i][j][stop[k]] + D[1][stop[k]];
			}
}

void solve() {
	bellman_ford();
    //dinamica();
	printf("%d\n", sol);
}

int main() {

    cit();
	solve();

	return 0;
}