Cod sursa(job #176853)

Utilizator plastikDan George Filimon plastik Data 11 aprilie 2008 19:35:04
Problema Team Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 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][PMAX];
int End[PMAX];
set<int> Cities;

void dijkstra(int src) {
	int i, alt, curr = src, ans, next;
	list<pair<int, int> >::iterator li;

	for (i = 1; i <= n; ++ i)
		Dist[src][i] = INT_MAX;
	Dist[src][src] = 0;
	
	bool stop = false;
	while (stop == false) {
		stop = true;

		for (li = Neighb[curr].begin(); li != Neighb[curr].end(); ++ li) {
			alt = Dist[src][curr] + li->second;
			if (alt < Dist[src][li->first]) {
				Dist[src][li->first] = alt;
				stop = false;
			}
		}

		ans = INT_MAX;
		next = -1;
		for (li = Neighb[curr].begin(); li != Neighb[curr].end(); ++ li)
			if (ans > Dist[src][curr] + li->second) {
				ans = Dist[src][curr] + li->second;
				next = li->first;
			}
		curr  = next;
	}
}

int main() {

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

	scanf("%d %d %d", &p, &n, &m);
	int i, v1, v2, c;
	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));
	}
	for (i = 1; i <= n; ++ i) {
		scanf("%d", &End[i]);
		Cities.insert(End[i]);
	}
	Cities.insert(1);

	for (i = 1; i <= n; ++ i)
		dijkstra(i);

	set<int>::iterator si;

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

	int j, k, l;
	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[l][i][*si] = INT_MAX;
				for (k = i; k <= j; ++ k)
					Ans[l][i][*si] = min(Ans[l][i][*si], Ans[k - i + 1][i][End[k]] + Ans[l - k][k + 1][End[k]] + Dist[*si][End[k]]);
			}
		}

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

	return 0;
}