Cod sursa(job #1725349)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 5 iulie 2016 15:04:06
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <cstdio>
#include <queue>
#include <algorithm>

#define nod first
#define cost second

using namespace std;

const int K = 15;
const int N = 2005;
const int inf = (1<<30)-1;

int city[K+5], d[(1<<K)+3][K+3], dist[N], k, n, m, i, X, Y, Cost, D[K+5][K+5], j, mask, ans;
vector< pair<int,int> > v[N];

void calculeaza_distante(int start)
{
    int i;
    for(i=1; i<=n; ++i) dist[i] = inf;
    dist[start]=0;

    queue<int> q;
    q.push(start);

    while(!q.empty())
    {
        int node = q.front();
        q.pop();

        for(i=0; i<v[node].size(); ++i)
            if( dist[ v[node][i].nod ] > dist[node] + v[node][i].cost )
            {
                dist[ v[node][i].nod ] = dist[node] + v[node][i].cost;
                q.push( v[node][i].nod );
            }
    }
}

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

    scanf("%d%d%d", &n, &m, &k);

    for(i=0; i<k; ++i)
        scanf("%d", &city[i]);

    city[k] = 1;
    city[k+1] = n;

    for(i=1; i<=m; ++i)
    {
        scanf("%d%d%d", &X, &Y, &Cost);
        v[X].push_back( {Y,Cost} );
        v[Y].push_back( {X,Cost} );
    }

    for(i=0; i<=k+1; ++i)
    {
        calculeaza_distante(city[i]);
        for(j=0; j<=k+1; ++j)
            D[i][j] = dist[city[j]];
    }

    for(mask=1; mask<(1<<k); ++mask)
        for(i=0;  i<k; ++i)
            d[mask][i] = inf;

    for(i=0; i<k; ++i)
        d[1<<i][i] = D[i][k];

    for(mask=1; mask<(1<<k); ++mask)
    {
         for(i=0; i<k; ++i)
         {
              for(j=0; j<k; ++j)
              if( !(mask&(1<<j)) )
                d[mask|(1<<j)][j] = min( d[mask|(1<<j)][j], d[mask][i] + D[i][j] );
         }
    }

    ans = inf;
    for(i=0; i<k; ++i)
        ans = min( ans, d[mask-1][i] + D[i][k+1] );

    printf("%d\n", ans);

    return 0;
}