Cod sursa(job #631683)

Utilizator DeadEyeNaiba Mihai Lucian DeadEye Data 9 noiembrie 2011 16:05:31
Problema Ubuntzei Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.72 kb
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;

const int maxN=2001;
const int INF=0x3f3f3f3f;

int sol,n,m,k,min_dist,min_nod,c[17];
int viz[maxN],ds[maxN];
int dmin[17][17],a[maxN][maxN],d[1<<15][17];

void read()
{
    int i,x,y,z;
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d",&n,&m);
    scanf("%d",&k);
    for(i=1;i<=k;++i)
        scanf("%d",&c[i]);
    c[0]=1; c[k+1]=n;
    for(i=1;i<=m;++i)
    {
        scanf("%d%d%d",&x,&y,&z);
        a[x][y]=z;
        a[y][x]=z;
    }
}
void dm(int x)
{
    int i,j;
    for(i=1;i<=n;++i) {
        ds[i]=INF;
        viz[i] = false;
    }
    ds[x]=0;

    for(i=1;i<=n;++i)
    {
        min_dist=min_nod=INF;
        for(j=1;j<=n;++j)
            if(!viz[j] && ds[j]<min_dist)
            {
                min_dist=ds[j];
                min_nod=j;
            }
        if (min_nod == INF) break;
        viz[min_nod]=1;
        for(j=1;j<=n;++j)
        {
            if(a[min_nod][j]>0 && ds[j]>a[min_nod][j]+min_dist)
                ds[j]=a[min_nod][j]+min_dist;
        }
    }
}
void work()
{
    int i,j,l,nx,ny;
    sol=INF;
    for(i=0;i<=k+1;++i)
    {
        dm(c[i]);
        for(j=0;j<=k+1;++j)
            dmin[i][j]=ds[c[j]];
    }

    memset(d,INF,sizeof(d));
    nx=1;
    for(i=1;i<=k;++i)
    {
        d[nx][i-1]=dmin[0][i];
        nx*=2;
    }
    nx=1<<k;
    for(i=1;i<nx;++i)
        for(j=0;j<k;++j)
            for(l=0;l<k;++l)
                if(i&(1<<j) && !(i&(1<<l)))
                    d[i|(1<<l)][l]=min(d[i|(1<<l)][l],d[i][j]+dmin[j+1][l+1]);
    for(i=0;i<k;++i)
        sol=min(sol,d[nx-1][i]+dmin[i+1][k+1]);
    printf("%d\n",sol);
}
int main()
{
    read();
    work();
    return 0;
}