Cod sursa(job #194857)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 14 iunie 2008 21:38:40
Problema Team Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <cstdio>
#include <queue>
#include <algorithm>
#include <list>
#include <vector>
using namespace std;
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define MAX_N 510
#define MAX_P 55
typedef list< pair<int,int> > lii;

int *pointer;
struct comp { bool operator()(int a, int b) { return pointer[a] > pointer[b]; } };

lii G[MAX_N];
int dest[MAX_P];
int n,m,p;
int Dist[MAX_N][MAX_N];

void load_data() {
	freopen( "team.in", "r", stdin );
	
	scanf("%d %d %d", &p, &n, &m);
	while ( m-- ) {
		int x, y, c; 
		scanf( "%d %d %d", &x, &y, &c );
		G[x].push_back( mp(y,c) );
		G[y].push_back( mp(x,c) );
	}
	for ( int i=0; i<p; ++i )
		scanf("%d", dest+i);
	dest[p++] = 1;
}

void dijkstrize() {
	int U[MAX_N]; memset(U, 0, sizeof(U));
	for (int i=0; i<p; ++i) {
		if ( U[ dest[i] ] ) continue;
		int x = dest[i]; U[ x ] = 1;
		
		int D[MAX_N];		memset( D, 0x3f, sizeof(D) );
		int enq[MAX_N];		memset( enq, 0, sizeof(enq));
		pointer = D;
		priority_queue<int, vector<int>, comp> Q;

		D[ x ] = 0;	enq[x] = 1;	Q.push(x);
		while ( ! Q.empty() ) {
			int fr = Q.top();
			for ( lii::iterator ii=G[fr].begin(); ii!=G[fr].end(); ++ii )
				if ( D[ii->f] > D[fr] + ii->s ) {
					D[ii->f] = D[fr] + ii->s;
					if ( !enq[ii->f] ) Q.push(ii->f), enq[ii->f] = 1;
				}
			Q.pop(); enq[fr] = 0;
		}

		for (int j=0; j<p; ++j)
			Dist[x][dest[j]] = D[ dest[j] ];
	}
}

int A[MAX_N][MAX_P][MAX_P];	// 1MB
int DP() {
	int i, j, k, l;
	// init
	for ( i=1; i<=n; ++i )
		for ( j=0; j<p; ++j )
			for ( k=0; k<p; ++k ) {
				if ( j>k )		A[i][j][k] = 0;
				if ( j==k )		A[i][j][k] = Dist[i][dest[j]];
				if ( j<k )		A[i][j][k] = 0x3fffffff;
			}

	// solve
	for ( l=2; l<p; ++l ) {
		for ( i=0; i<p; ++i )			// suntem in orasul dest[i]
			for ( j=0; j+l-1<p; ++j ) {	// avem in taxi intre j..j+l-1
				for ( k=j; k<=j+l-1; ++k )
					A[dest[i]][j][j+l-1] = min( A[dest[i]][j][j+l-1], A[dest[k]][j][k-1]+A[dest[k]][k+1][j+l-1]+Dist[dest[i]][dest[k]] );
			}
	}
	return A[1][0][p-2];
}

int main() {
	load_data();
	dijkstrize();
	fprintf( fopen("team.out", "w"), "%d\n", DP() );
	return 0;
}