Cod sursa(job #91112)

Utilizator sealTudose Vlad seal Data 11 octombrie 2007 17:52:44
Problema Team Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include<stdio.h>
#include<string.h>
#define Pm 50
#define Nm 501
#define Inf 1000000000
#define min(a,b) ((a)<(b)?(a):(b))
int C[Nm][Nm],A[Pm][Pm][Pm],Dm[Pm][Nm],M[Nm],D[Pm],p,n,m,ans;

void read()
{
    int m,x,y,c;

    freopen("team.in","r",stdin);
    scanf("%d%d%d",&p,&n,&m);
    for(x=1;x<=n;++x)
        for(y=1;y<=n;++y)
            C[x][y]=Inf;
    while(m--)
    {
        scanf("%d%d%d",&x,&y,&c);
        C[x][y]=C[y][x]=c;
    }
    for(x=0;x<p;++x)
        scanf("%d",D+x);
}

void Dijkstra(int s, int Dm[])
{
    int i,x,dm;

    memset(M,0,sizeof(M));
    for(i=1;i<=n;++i)
        Dm[i]=Inf;
    Dm[s]=0;

    while(1)
    {
        dm=Inf;
        for(i=1;i<=n;++i)
            if(!M[i] && Dm[i]<dm)
            {
                dm=Dm[i];
                x=i;
            }

        if(dm==Inf)
            break;
        M[x]=1;
        for(i=1;i<=n;++i)
            Dm[i]=min(Dm[i],dm+C[x][i]);
    }
}

void solve()
{
    int P[Pm][Pm],Np[Pm],Dest[Pm],Poz[Pm],d,i,j,k,l,v,nd=0;

    for(i=0;i<p;++i)
        M[D[i]]=1;
    for(i=1;i<=n;++i)
        if(M[i])
            Dest[nd++]=i;
    memset(Np,0,sizeof(Np));
    for(i=0;i<p;++i)
        for(j=0;;++j)
            if(D[i]==Dest[j])
            {
                Poz[i]=j;
                P[j][Np[j]++]=i;
                break;
            }

    for(i=0;i<nd;++i)
        Dijkstra(Dest[i],Dm[i]);

    for(l=0;l<p;++l)
        for(i=0;i<p-l;++i)
        {
            j=i+l;
            for(d=0;d<nd;++d)
            {
                for(k=0;k<Np[d] && (P[d][k]>j || P[d][k]<i);++k);
                if(k<Np[d])
                {
                    A[i][j][d]=0;
                    if(P[d][k]>i)
                        A[i][j][d]+=A[i][P[d][k]-1][d];
                    if(P[d][k]<j)
                        A[i][j][d]+=A[P[d][k]+1][j][d];
                    A[i][j][d]=min(A[i][j][d],Inf);
                    continue;
                }
                A[i][j][d]=Inf;
                for(k=i;k<=j;++k)
                {
                    v=Dm[d][D[k]];
                    if(k>i)
                    {
                        v+=A[i][k-1][Poz[k]];
                        v=min(v,Inf);
                    }
                    if(k<j)
                    {
                        v+=A[k+1][j][Poz[k]];
                        v=min(v,Inf);
                    }
                    A[i][j][d]=min(A[i][j][d],v);
                }
            }
        }

    ans=Inf;
    for(d=0;d<nd;++d)
        ans=min(ans,Dm[d][1]+A[0][p-1][d]);
}

void write()
{
    freopen("team.out","w",stdout);
    printf("%d\n",ans);
}

int main()
{
    read();
    solve();
    write();
    return 0;
}