Cod sursa(job #1612470)

Utilizator Corneliu10Dumitru Corneliu Corneliu10 Data 24 februarie 2016 21:13:56
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <set>
#include <cstring>
#define inf 1<<30
#define Nmax 2100
#define Kmax 16

using namespace std;

int c[Nmax];
vector <int> G[Nmax];
vector <int> Cost[Nmax];
int n,m,k;

int d[Nmax];
int dist[Kmax][Nmax];///distance from node l to c

int best[1<<Kmax][Kmax];///2^s submultimi si k elem - distanta pana la Ck continand s elem

void Dijkstra(int start)
{
    int i,nod,val;
    for(i=1;i<=n;i++)
        d[i] = inf;
    d[start] = 0;

    queue < pair<int , int> > T;
    T.push( make_pair(start, 0) );

    while(!T.empty())
    {
        nod = (T.front()).first;
        val = (T.front()).second;
        T.pop();

        for(i=0;i < G[nod].size();i++)
            if(d[G[nod][i]] > d[nod] + Cost[nod][i])
            {
                d[G[nod][i]] = d[nod] + Cost[nod][i];
                T.push( make_pair(G[nod][i], d[G[nod][i]]) );
            }
    }
}

int bit(int s,int x)
{
    return (s & (1<<x)) != 0;
}

void dp()
{
    int i,j,l,sm;

    for(i=1;i < (1<<k);i++)
    {
        for(j=0;j<k;j++)
            if(i == (1<<j))
                break;
        if(i == (1<<j))
        {
            best[i][j] = dist[k][c[j]];
            continue;
        }

        for(j=0;j<k;j++)
            if(bit(i,j))
            {
                sm = inf;
                for(l = 0;l < k;l++)
                    if(l!=j && bit(i,l))
                        sm = min(sm, best[i - (1<<j)][l] + dist[l][c[j]]);

                best[i][j] = sm;
            }
    }

}

int main()
{
    int i,j,a,y,z;
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);

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

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

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&a,&y,&z);
        G[a].push_back(y);
        G[y].push_back(a);

        Cost[a].push_back(z);
        Cost[y].push_back(z);
    }

    Dijkstra(1);
    memcpy(dist[k],d,sizeof(d));

    for(i=0;i<k;i++)
    {
        Dijkstra(c[i]);
        memcpy(dist[i],d,sizeof(d));
    }

    if(k==0)
    {
        printf("%d",dist[k][n]);
        return 0;
    }

    dp();

    int sol = inf;

    for(i = 0;i<k;i++)
        if( best[(1<<k) - 1][i] + dist[i][n] < sol ) sol = best[(1<<k) - 1][i] + dist[i][n];

    printf("%d",sol);
}