Cod sursa(job #584117)

Utilizator borsoszalanBorsos Zalan borsoszalan Data 24 aprilie 2011 10:06:36
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

#define pb push_back
#define mp make_pair
#define sc second
#define fs first

#define INF 0x3f3f3f3f
#define LIM 32775
#define DIM 2005
#define MAX 20

vector <pair <int,int> > g[DIM];
int cst[MAX][MAX],bst[LIM][MAX];
int v[MAX],dst[DIM];
int N,M,K,nrt_min;
bool viz[DIM];

struct cmp
{
    bool operator () (const int &a,const int &b)
    {
        return dst[a]>dst[b];
    }
}; priority_queue <int,vector <int>,cmp> q;

void read ()
{
    int i,x,y,z;
    scanf ("%d%d%d",&N,&M,&K);
    v[0]=1;
    for (i=1; i<=K; ++i)
        scanf ("%d",&v[i]);
    v[K+1]=N;
    for (i=1; i<=M; ++i)
    {
        scanf ("%d%d%d",&x,&y,&z);
        g[x].pb (mp (y,z));
        g[y].pb (mp (x,z));
    }
}

inline void dijkstra (int SRC)
{
    vector <pair <int,int> > :: iterator it;
    int nod;
    memset (dst,INF,sizeof (dst));
    memset (viz,0,sizeof (viz));
    dst[SRC]=0;
    for (q.push (SRC); !q.empty (); )
    {
        nod=q.top (); viz[nod]=0; q.pop ();
        for (it=g[nod].begin (); it!=g[nod].end (); ++it)
            if (dst[nod]+it->sc<dst[it->fs])
            {
                dst[it->fs]=dst[nod]+it->sc;
                if (!viz[it->fs])
                {
                    viz[it->fs]=1;
                    q.push (it->fs);
                }
            }
    }
}

void solve ()
{
    int stare,oldstare,i,j;
    for (i=0; i<=K; ++i)
    {
        dijkstra (v[i]);
        for (j=1; j<=K+1; ++j)
            cst[i][j]=dst[v[j]];
    }
    if (!K)
    {
        printf ("%d",cst[0][1]);
        return ;
    }
    memset (bst,INF,sizeof (bst));
    for (stare=1; stare<(1<<K); ++stare)
        for (i=1; i<=K; ++i)
            if (stare&(1<<(i-1)))
            {
                oldstare=stare^(1<<(i-1));
                if (!oldstare)
                    bst[stare][i]=cst[0][i];
                else
                    for (j=1; j<=K; ++j)
                        if (oldstare&(1<<(j-1)))
                            bst[stare][i]=min (bst[stare][i],bst[oldstare][j]+cst[i][j]);
            }
    nrt_min=INF;
    for (i=1; i<=K; ++i)
        nrt_min=min (nrt_min,bst[(1<<K)-1][i]+cst[i][K+1]);
    printf ("%d",nrt_min);

}

int main ()
{
    freopen ("ubuntzei.in","r",stdin);
    freopen ("ubuntzei.out","w",stdout);
    read ();
    solve ();
    return 0;
}