Cod sursa(job #36200)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 23 martie 2007 10:20:27
Problema Team Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <cstdio>
#include <vector>
#include <set>

using namespace std;

#define MAXN 505
#define MAXP 55

int P, N, M;
vector< pair<int, int> > con[MAXN];

int d[MAXP];

int dist[MAXN][MAXN];

int nr[MAXN][MAXP][MAXP];

int solve( int k, int l, int r )
{
	if (nr[k][l][r] != 0x3f3f3f3f)
		return nr[k][l][r];

	if (l == r)
		return nr[k][l][r] = dist[k][ d[l] ];

	int found = 0;
	for (int i = l; i <= r && !found; i++)
		if (d[i] == k)
			found = 1;

	if (found)
	{
		int rez = 0, last, i;
		for (i = l; d[i] == k && i <= r; i++);

		for (last = i; i <= r; )
			if (d[i] == k)
			{
				rez += solve(k, last, i - 1);
				for (; d[i] == k && i <= r; i++);
				last = i;
			}
			else
				i++;

		if (last <= r)
			rez += solve( k, last, r );
		return nr[k][l][r] = rez;
	}

	for (int i = l; i <= r; i++)
	{
		int rez = dist[k][ d[i] ] + solve( d[i], l, r );
		if (rez < nr[k][l][r])
			nr[k][l][r] = rez;
	}
	return nr[k][l][r];
}

set< pair<int, int> > S;

inline void dijkstra( int k )
{
	dist[k][k] = 0; S.clear();
	for (int i = 1; i <= N; i++)
		S.insert( make_pair( dist[k][i], i ) );

	for (; !S.empty(); )
	{
		int cur = (*S.begin()).second, cst = (*S.begin()).first;
		S.erase( S.begin() );

		vector< pair<int, int> > :: iterator it;
		for (it = con[cur].begin(); it != con[cur].end(); it++)
		{
			int nxt = (*it).first, ncst = cst + (*it).second;

			if (ncst < dist[k][nxt])
			{
				S.erase( S.find( make_pair( dist[k][nxt], nxt ) ) );
				dist[k][nxt] = ncst;
				S.insert( make_pair( dist[k][nxt], nxt ) );
			}
		}
	}
}

int main()
{
	freopen("team.in", "rt", stdin);
	freopen("team.out", "wt", stdout);

	memset(dist, 0x3f, sizeof(dist));
	memset(nr, 0x3f, sizeof(nr));
	for (scanf("%d %d %d", &P, &N, &M); M; M--)
	{
		int i, j, k;
		scanf("%d %d %d", &i, &j, &k);
		con[i].push_back( make_pair(j, k) );
		con[j].push_back( make_pair(i, k) );
	}
	for (int i = 1; i <= P; i++)
		scanf("%d", d + i);

	dijkstra(1);
	for (int k = 1; k <= P; k++)
	{
		if (dist[ d[k] ][ d[k] ] == 0)
			continue;
		dijkstra( d[k] );
	}

	printf("%d\n", solve(1, 1, P));

	return 0;
}