Cod sursa(job #633147)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 13 noiembrie 2011 00:00:47
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

const int inf=0x3f3f3f3f;
inline int min(int x,int y){if (x<y) return x;else return y;}
struct str{int x,y;};
inline str mp(int x,int y){str aux;aux.x=x;aux.y=y;return aux;}

int n,d[32768][17],d2[751],a[17][17][17],cnt[65536],p[17];
vector <int> lim[751];
vector <str> g[751];
queue <int> q;

void intr(int x,int y)
{
    int i,j;
    unsigned int k;
    for(i=1;i<=n;++i)
        d2[i]=inf;
    q.push(x);
    d2[x]=0;
    while(q.size()>0)
    {
        j=q.front();
        q.pop();
        for(k=0;k<g[j].size();++k)
            if(d2[j]+g[j][k].y<d2[g[j][k].x]&&lim[j][k]>=y)
            {
                d2[g[j][k].x]=d2[j]+g[j][k].y;
                q.push(g[j][k].x);
            }
    }
}

int main()
{
    int i,j,l,sol=inf,aux,aux2,aux3,x,y,z,t,k,m;
    freopen("gather.in","r",stdin);
    freopen("gather.out","w",stdout);
    scanf("%d%d%d",&k,&n,&m);
    for (p[0]=1,i=1;i<=k;++i)
        scanf("%d",&p[i]);
    for(;m;--m)
    {
        scanf("%d%d%d%d\n",&x,&y,&z,&t);
        lim[x].push_back(t+1);
        lim[y].push_back(t+1);
        g[x].push_back(mp(y,z));
        g[y].push_back(mp(x,z));
    }
    for(i=1;i<65536;++i)
        cnt[i]=cnt[i>>1]+(i&1);
    for(i=0;i<65536;++i)
        ++cnt[i];
    for(i=0;i<=k;++i)
        for(j=1;j<=k+1;++j)
        {
            intr(p[i],j);
            for(l=0;l<=k;++l)
                a[i][l][j]=d2[p[l]];
        }
    for(aux=0;aux<(1<<k);++aux)
        for(x=0;x<=k;++x)
            d[aux][x]=inf;
    d[0][0]=0;
    for(aux=1;aux<(1<<k);++aux)
        for(x=1;x<=k;++x)
            if(aux&(1<<(x-1)))
            {
                for(aux3=inf,y=0;y<=k;++y)
                    if(x!=y&&a[y][x][cnt[aux2=aux^(1<<(x-1))]]!=inf)
                        aux3=min(aux3,d[aux2][y]+a[y][x][cnt[aux2]]*cnt[aux2]);
                d[aux][x]=aux3;
            }
    for(i=1;i<=k;++i)
        sol=min(sol,d[(1<<k)-1][i]);
    printf("%d\n",sol);
    return 0;
}