Cod sursa(job #296452)

Utilizator CezarMocanCezar Mocan CezarMocan Data 4 aprilie 2009 20:08:48
Problema Team Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <cstdio>
#include <vector>
#include <set>
#define maxn 512
#define maxp 55
#define inf 1000000000

using namespace std;

int i, j, a, b, c, p, n, m, k;
vector <int> v[maxn], cs[maxn];
int dmin[maxn][maxn], done[maxp];
int d[maxp];
bool viz[maxn][maxp][maxp];
int dnk[maxn][maxp][maxp];

void dijkstra(int nod) {
	int i, j, fiu, cost, fnou, cnou;
	set <pair<int, int> > dist;
	set <pair<int, int> >::iterator it, it2; 
	dist.clear();

	dist.insert(make_pair(0, nod));

	dmin[nod][nod] = 0;
	for (i = 1; i <= n; i++)
		if (i != nod)
			dist.insert(make_pair(dmin[nod][i], i));

	for (i = 1; i <= n - 1; i++) {
		it = dist.begin();

		fiu = it->second;
		cost = it->first;

		for (j = 0; j < v[fiu].size(); j++) {
			if (dmin[nod][v[fiu][j]] > cost + cs[fiu][j]) {
				it2 = dist.find(make_pair(dmin[nod][v[fiu][j]], v[fiu][j]));
				if (it2 != dist.end())
					dist.erase(it2);

				cnou = cost + cs[fiu][j];
				fnou = v[fiu][j];

				dist.insert(make_pair(cnou, fnou));
				dmin[nod][v[fiu][j]] = cnou;
			}
		}
		dist.erase(it);
	}
}

inline int min(int a, int b) {
	if (a < b)
		return a;
	return b;
}

int baga(int nod, int left, int right) {
	int i, sol;
	if (viz[nod][left][right])
		return dnk[nod][left][right];
	viz[nod][left][right] = 1;
	
	if (left > right)
		return 0;
    sol = inf;

	for (i = left; i <= right; i++) 
		sol = min(sol, baga(d[i], left, i - 1) + baga(d[i], i + 1, right) + dmin[nod][d[i]]);

//	fprintf(stderr, "%d %d %d   %d\n", nod, left, right, dnk[nod][left][right]);
	
	dnk[nod][left][right] = sol;
	return dnk[nod][left][right];

}

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

	scanf("%d%d%d", &p, &n, &m);

	for (i = 1; i <= m; i++) {
		scanf("%d%d%d", &a, &b, &c);
		v[a].push_back(b);
		cs[a].push_back(c);

		v[b].push_back(a);
		cs[b].push_back(c);
	}

	for (i = 1; i <= n; i++)
		for (j = 1; j <= n; j++)
			dmin[i][j] = inf;

    for (i = 0; i < maxn; i++)
        for (j = 0; j < maxp; j++)
            for (k = 0; k < maxp; k++)
                dnk[i][j][k] = inf;

	dijkstra(1);
	done[1] = 1;
	for (i = 1; i <= p; i++) {
		scanf("%d", &d[i]);
		if (!done[d[i]]) {
			dijkstra(d[i]);
			done[d[i]] = 1;
		}

	}

	printf("%d\n", baga(1, 1, p));
	return 0;
}