Cod sursa(job #34302)

Utilizator astronomyAirinei Adrian astronomy Data 20 martie 2007 16:59:58
Problema Team Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <stdio.h>
#include <string.h>

#define INF (1 << 28)
#define MAX_P 64
#define MAX_N 512

int N, M, P, d[MAX_P], G[MAX_N][MAX_N], C[MAX_N][MAX_N];
int A[MAX_P][MAX_P][MAX_N];

int min(int a, int b)
{
    return (a < b ? a : b);
}

int solve(int x, int y, int t)
{
    int i, j, k, best;

    if(y == x-1 || x == y+1)
        return 0;

    if(A[x][y][t] != -1)
        return A[x][y][t];

    for(best = INF, k = x; k <= y; k++)
        best = min(best,
            C[t][d[k]] + solve(x, k-1, d[k]) + solve(k+1, y, d[k]));

    return (A[x][y][t] = best);
}

int uz[MAX_N], dist[MAX_N];

void dijkstra(int src)
{
    int ok, i, j, min;

    for(memset(uz, 0, sizeof(uz)), uz[src] = 1, i = 1; i <= N; i++)
        dist[i] = G[src][i];

    while(1)
    {
        for(min = INF, i = 1; i <= N; i++)
         if(!uz[i] && dist[i] < min)
            min = dist[i], j = i;

        if(min == INF)
            break ;

        for(uz[j] = 1, i = 1; i <= N; i++)
         if(!uz[i] && dist[i] > dist[j]+G[j][i])
            dist[i] = dist[j] + G[j][i];
    }

    for(i = 1; i <= N; i++)
        C[src][i] = dist[i];
}

void read_data(void)
{
    int i, j, k, c;

    scanf("%d\n%d\n%d\n", &P, &N, &M);

    for(i = 1; i <= N; i++)
     for(j = 1; j <= N; j++)
        G[i][j] = (i == j ? 0 : INF);

    for(i = 1; i <= M; i++)
    {
        scanf("%d %d %d\n", &j, &k, &c);
        if(G[j][k] > c)
            G[j][k] = G[k][j] = c;
    }

    for(i = 1; i <= P; i++)
        scanf("%d ", &d[i]);
}

void ruleaza(void)
{
    int i, j, k;

    read_data();
    
    for(dijkstra(1), i = 1; i <= P; i++)
        dijkstra(d[i]);

    for(i = 1; i <= P; i++)
     for(j = 1; j <= P; j++)
      for(k = 1; k <= N; k++)
        A[i][j][k] = -1;

    for(i = 1; i <= P; i++)
        A[i][i][d[i]] = 0;
        
    printf("%d\n", solve(1, P, 1));
}

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

    ruleaza();

    return 0;
}