Cod sursa(job #35008)

Utilizator unholyfrozenCostea Andrei unholyfrozen Data 21 martie 2007 18:40:50
Problema Team Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.97 kb
#include<stdio.h>
#include<string.h>

#define NMAX 512
#define INF 999999999

void read();
void solve();
void update(int &x, int y);

int P, N, M, C[NMAX][NMAX], d[64], seen[NMAX], D[NMAX][NMAX], V[64][64][2];

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

     read();
     solve();
	return 0;
}

void read()
{
	int i, a, b, c, j;
     
	scanf("%d%d%d", &P, &N, &M);
     for(i = 0; i < N; i++)
     for(j = 0; j < N; j++)
     if(i != j) C[i][j] = INF;
     
     for(i = 0; i < M; i++)
     {
     	scanf("%d%d%d", &a, &b, &c);
          a--, b--;
          C[a][b] = C[b][a] = c;
     }
     for(i = 1; i <= P; i++)
     {
		scanf("%d", d + i);
          d[i]--;
     }
}

void solve()
{
	int i, j, k, src, min, z;

	for(k = 0; k <= P; k++)
     {
          src = d[k];
          memset(seen, 0, sizeof(seen));
          for(i = 0; i <= N; i++)
          D[src][i] = INF;
          D[src][src] = 0;
          for(i = 0; i < N; i++)
          {
          	min = N;
          	for(j = 0; j < N; j++)
               if(!seen[j] && D[src][j] < D[src][min])
               min = j;

               if(seen[min]) break;
               seen[min] = 1;

               for(j = 0; j < N; j++)
               if(!seen[j] && D[src][j] > D[src][min] + C[min][j])
               D[src][j] = D[src][min] + C[min][j];
          }
     }
     for(k = 0; k <= P; k++)
     for(i = 1; i + k <= P; i++)
     {
     	j = i + k;
          V[i][j][0] = V[i][j][1] = INF;
          if(i == j)
          {
          	V[i][j][0] = D[d[i - 1]][d[i]];
               V[i][j][1] = D[d[i + 1]][d[i]];
               continue;
          }
          for(z = i; z <= j; z++)
		{
          	update(V[i][j][0], D[d[i - 1]][d[z]] + (z > i ? V[i][z - 1][1] : 0) + (z < j ? V[z + 1][j][0] : 0));
               update(V[i][j][1], D[d[j + 1]][d[z]] + (z > i ? V[i][z - 1][1] : 0) + (z < j ? V[z + 1][j][0] : 0));
          }
     }
     printf("%d\n", V[1][P][0]);
}

void update(int &x, int y)
{
	if(x > y) x = y;
}