Cod sursa(job #35275)

Utilizator azotlichidAdrian Vladu azotlichid Data 21 martie 2007 22:50:06
Problema Team Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.79 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define FOR(i, a, b) for (i = (a); i <= (b); i ++)
#define REP(i, n)    for (i =   0; i <  (n); i ++)
#define CLEAR(X)     memset((X), 0, sizeof((X)))
#define INF          1099999999

#define PMAX 55
#define NMAX 505

int P, N, M, stp, i, j, k, aux;
int D[PMAX];
int a[NMAX][NMAX], m[NMAX][NMAX];
int o[PMAX][PMAX][NMAX];

void read(void)
{
    freopen("team.in", "r", stdin);
    freopen("team.out", "w", stdout);
    scanf("%d %d %d", &P, &N, &M);

    memset(a, 0xFF, sizeof(a));
    REP(stp, M)
    {
        scanf("%d %d %d", &i, &j, &k);
        if (a[i][j] == -1 || k < a[i][j]) a[i][j] = a[j][i] = k;
    }
    FOR(i, 1, P)
           scanf("%d", &D[i]);
}

int seen[NMAX];
int extract_min(int o[])
{
    int ret = -1, i, min = INF;
    FOR(i, 1, N)
       if (!seen[i] && o[i] != -1 && o[i] < min)
          min = o[i], ret = i;
    return ret;
}

void relax(int node, int o[])
{
    int i;
    FOR(i, 1, N)
           if (!seen[i] && a[node][i] != -1 && (o[i] == -1 || o[i] > o[node] + a[node][i]))
              o[i] = o[node] + a[node][i];
}

void dijkstra(int src, int o[])
{
    memset(seen, 0, sizeof(seen));
    memset(o, 0xFF, (N + 1) * sizeof(int));
    o[src] = 0;

    int i, node;
    FOR(i, 1, N)
    {
        node = extract_min(o);
        if (node == -1) return;
        seen[node] = 1, relax(node, o);
    }
}

void baga(int b, int e, int n)
{
    if (b == e)
        o[b][e][n] = m[n][D[b]];
    else
    {
        int i, aux;
        o[b][e][n] = INF;
        FOR(i, b, e)
        {
            aux = m[n][D[i]];
            if (b < i)
            {
                if (o[b][i - 1][D[i]] == -1) baga(b, i - 1, D[i]);
                aux += o[b][i - 1][D[i]];
            }
               
            if (i < e)
            {
                if (o[i + 1][e][D[i]] == -1) baga(i + 1, e, D[i]);
                aux += o[i + 1][e][D[i]];
            }
            
            if (aux < o[b][e][n])
               o[b][e][n] = aux;
        }
    }
}

void solve(void)
{
    memset(m, 0xFF, sizeof(m));
    
    D[0] = 1;
    FOR(i, 0, P)
    {
           k = D[i];
           dijkstra(k, m[k]);
           FOR(j, 1, N) if (m[j][k] == -1) m[j][k] = m[k][j];
    }
    FOR(i, 1, N) m[i][i] = 0;

    memset(o, 0xFF, sizeof(o));
    baga(1, P, 1);
    printf("%d\n", o[1][P][1]);
}

void gen(void)
{
    freopen("team.in", "w", stdout);
    P = 50, N = 500; M = N - 1;//N * (N - 1) / 2;
    printf("%d\n%d\n%d\n", P, N, M);
    /*
    FOR(i, 1, N - 1)
           FOR(j, i + 1, N)
                  printf("%d %d %d\n", i, j, rand() % 10000);
    */
    FOR(i, 1, N - 1)
        printf("%d %d %d\n", i, i + 1, 1);
    FOR(i, 1, N)
           printf("%d ", 1 + rand() % N);
    printf("\n");
}

int main(void)
{
//    gen();
//    return 0;
    read();
    solve();
    return 0;
}