Cod sursa(job #1646972)

Utilizator LipanmateiLipan Radu-Matei Lipanmatei Data 10 martie 2016 18:28:35
Problema Ubuntzei Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

#define Nmax 2001
#define INF ((1<<16)-1)
using namespace std;
//ifstream fin("ubuntzei.in");
//ofstream fout("ubuntzei.out");
int n,m,k;
vector < pair <int,int> > v[Nmax];
vector < int > ubu;
vector < int > dist[20];
vector < int > D[18];

void read()
{
    freopen("ubuntzei.in", "rt", stdin);
    freopen("ubuntzei.out", "wt", stdout);
    //fin>>n>>m;
    //fin>>k;
    scanf("%d%d%d", &n, &m, &k);
    ubu.push_back(1);
    for(int i=1;i<=k;++i)
    {
        int c;
        //fin>>c;
        scanf("%d", &c);
        ubu.push_back(c);
    }
    ubu.push_back(n);
    for(int i=1;i<=m;++i)
    {
        int x,y,cost;
        //fin>>x>>y>>cost;
        scanf("%d%d%d", &x, &y, &cost);
        v[y].push_back(make_pair(x,cost));
        v[x].push_back(make_pair(y,cost));
    }
}

void B_F(int i_start)
{
    int start=ubu[i_start];
    queue < int > Q;
    dist[i_start].assign(n+2,INF);
    dist[i_start][start]=0;
    Q.push(start);
    while(!Q.empty())
    {
        int nod = Q.front();
        Q.pop();
        int d = dist[i_start][nod];
        int vecin,dvecin;
        for(int i=0;i<v[nod].size();i++)
        {
            vecin=v[nod][i].first;
            dvecin=v[nod][i].second;
            if(d+dvecin< dist[i_start][vecin])
            {
                dist[i_start][vecin]=d+dvecin;
                Q.push(vecin);
            }
        }
    }
}

void initdrum()
{
    for(int i=0; i<=k+2 ; ++i)
        D[i].assign(1<<(k+3), INF);
}

int construire_drum(int i_nod_final,int cod)
{
    if(cod==0)
        return dist[0][ubu[i_nod_final]];
    if(D[i_nod_final][cod]<INF)
        return D[i_nod_final][cod];
    for(int i=1;i<=k;i++)
    {
        int val = INF;
        if(cod>>(i-1)&1)
        {
            val=construire_drum(i,cod-(1<<(i-1)));
            val+=dist[i][ubu[i_nod_final]];
        }
        if(val < D[i_nod_final][cod])
            D[i_nod_final][cod] = val;
    }
    return D[i_nod_final][cod];
}
int main()
{
    read();
    for(int i=0;i<ubu.size()-1;++i)
        B_F(i);
    initdrum();
    printf("%d",construire_drum(k+1,(1<<k)-1));
    return 0;
}