Cod sursa(job #430390)

Utilizator DraStiKDragos Oprica DraStiK Data 30 martie 2010 22:42:17
Problema Gather Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.25 kb
#include <algorithm>
#include <vector>
using namespace std;

#define INF 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define sc second
#define fs first
#define DIM 755
#define MAX 20

vector <pair <int,pair <int,int> > > g[DIM];
int dst[DIM],h[DIM],poz[DIM],nrb[1<<MAX];
int best[MAX][MAX][MAX];
int dp[MAX][1<<MAX];
vector <int> det;
int p,n,m,l,rez;

void read ()
{
    int i,x,y,z,t;

    scanf ("%d%d%d",&p,&n,&m);
    for (i=1; i<=p; ++i)
    {
        scanf ("%d",&x);
        det.pb (x);
    }
    for (i=1; i<=m; ++i)
    {
        scanf ("%d%d%d%d",&x,&y,&z,&t);
        g[x].pb (mp (y,mp (z,t)));
        g[y].pb (mp (x,mp (z,t)));
    }
}

inline void upheap (int nod)
{
    int tata;

    for ( ; nod>1; )
    {
        tata=nod>>1;
        if (dst[h[tata]]>dst[h[nod]])
        {
            poz[h[tata]]=nod;
            poz[h[nod]]=tata;
            swap (h[tata],h[nod]);
            nod=tata;
        }
        else
            return ;
    }
}

inline void downheap (int nod)
{
    int fiu;

    for ( ; fiu<=l; )
    {
        if ((nod<<1)<=l)
        {
            fiu=nod<<1;
            if(fiu+1<=l)
                if (dst[h[fiu+1]]<dst[h[fiu]])
                    ++fiu;
        }
        else
            return ;

        if (dst[h[fiu]]<dst[h[nod]])
        {
            poz[h[nod]]=fiu;
            poz[h[fiu]]=nod;
            swap (h[nod],h[fiu]);
            nod=fiu;
        }
        else
            return ;
    }
}

inline void dijkstra (int s,int lim)
{
    vector <pair <int,pair <int,int> > > :: iterator it;
    int nod;

    memset (poz,0,sizeof (poz));
    memset (dst,INF,sizeof (dst));
    for (dst[h[poz[s]=l=1]=s]=0; l; )
    {
        nod=h[1];
        h[1]=h[l--];
        poz[h[1]]=1;
        downheap (1);
        for (it=g[nod].begin (); it!=g[nod].end (); ++it)
            if (dst[nod]+it->sc.fs<dst[it->fs] && it->sc.sc>=lim)
            {
                dst[it->fs]=dst[nod]+it->sc.fs;
                if (poz[it->fs])
                    upheap (poz[it->fs]);
                else
                {
                    poz[h[++l]=it->fs]=l;
                    upheap (l);
                }
            }
    }
}

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

    for (i=0; i<(int)det.size (); ++i)
        for (j=1; j<=p; ++j)
        {
            dijkstra (det[i],j);
            for (k=0; k<(int)det.size (); ++k)
                best[i][k][j]=dst[det[k]];
        }
    dijkstra (1,0);
    memset (dp,INF,sizeof (dp));
    for (i=0; i<(int)det.size (); ++i)
        dp[i][1<<i]=dst[det[i]];
    for (i=0; i<(1<<p); ++i)
        nrb[i]=nrb[i>>1]+(i&1);
    for (i=0; i<(1<<p); ++i)
        for (j=0; j<(int)det.size (); ++j)
            if (!(i&(1<<j)))
                for (k=0; k<(int)det.size (); ++k)
                    if ((i&(1<<k)) && best[j][k][nrb[i]]!=INF)
                        dp[j][i|(1<<j)]=min (dp[j][i|(1<<j)],dp[k][i]+(nrb[i]+1)*best[j][k][nrb[i]]);
    rez=INF;
    for (i=0; i<(int)det.size (); ++i)
        rez=min (rez,dp[i][(1<<p)-1]);
    printf ("%d",rez);
}

int main ()
{
    freopen ("gather.in","r",stdin);
    freopen ("gather.out","w",stdout);

    read ();
    solve ();

    return 0;
}